question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ASP.NET Core 3 signatures

See original GitHub issue

I have been thinking about what we have in #112 and what we can do there. I have been thinking Carter could expose the ASP.NET Core APIs yet still offer its own features. This means we could offer the same as ASP.NET Core APIs such as this.Get("/", ctx => ctx.WriteAsync("hi").RequiresAuth().RequiresHost() however I am currently unsure how to wire this up.

We currently do this for ASPNET3 https://github.com/CarterCommunity/Carter/blob/aspnetcore3/src/CarterExtensions.cs#L58 but I’m not sure if CarterModule should expose a list of IEndpointConventionBuilder potentially and then wire that up to the endpoint routing middleware.

Hoping @davidfowl can help point in the right direction

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
jchannoncommented, Oct 11, 2019

Yup, I see, got it. Got onion layers going on…

Thanks

On Fri, 11 Oct 2019 at 04:06, David Fowler notifications@github.com wrote:

@davidfowl https://github.com/davidfowl Is there a difference in using your IEndpointConventionBuilder examples and EndpointDataSource like below

Not sure what you mean? It’s typical for extension methods to return IEndpointConventionBuilder so callers can add metadata to routes.

I also can’t see when CompositeConventionBuilder.Add would be called?

CompositeConventionBuilder implements IEndpointConventionBuilder which is where Add comes from. When you call something like RequireAuthorization it calls Add on the builder https://github.com/aspnet/AspNetCore/blob/16a47948f80fede807fabe3c291d793590e8fd17/src/Security/Authorization/Policy/src/AuthorizationEndpointConventionBuilderExtensions.cs#L82. It’s how all conventions work.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CarterCommunity/Carter/issues/207?email_source=notifications&email_token=AAAZVJV76NCYIR3RZ4F7K5DQN7UR7A5CNFSM4I3XQTA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEA6TAYA#issuecomment-540880992, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAZVJVO6MAWQ4OCTSQB37TQN7UR7ANCNFSM4I3XQTAQ .

1reaction
davidfowlcommented, Sep 30, 2019

UseCarter should hang off IEndpointConventionBuilder instead of hanging off IApplicationBuilder (and would be renamed to MapCarter).

Middleware can act on selected endpoints when chosen so things like authorization/cors can be moved outside of the framework into middleware. As part of route registration users should have a way to add metadata to their route.

public class ProductsModule : CaterModule
{
    public MyModule() : base("/products")
    {
        this.Get("/", ctx => ctx.WriteAsync("hi")).RequireAuthorization();
    }
}

The CarterModule would be a mini DSL over routing.

Quickly looking at the code I’m not sure how you could expose the IEndpointConventionBuilder from the route registration methods without a breaking change. Maybe it could be an argument instead?

Here’s a strawman:

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace CarterDemo
{
    public class HelloModule : CarterModule
    {
        public HelloModule()
        {
            Get("/", context => context.Response.WriteAsync("Hello World")).RequireAuthorization();
        }
    }

    public class CarterModule
    {
        internal readonly Dictionary<(string verb, string path), (RequestDelegate handler, RouteConventions conventions)> Routes = new Dictionary<(string verb, string path), (RequestDelegate handler, RouteConventions conventions)>();

        public IEndpointConventionBuilder Get(string path, RequestDelegate handler)
        {
            var conventions= new RouteConventions();
            Routes.Add((HttpMethods.Get, path), (handler, conventions));
            return conventions;
        }

        internal class RouteConventions : IEndpointConventionBuilder
        {
            private readonly List<Action<EndpointBuilder>> _actions = new List<Action<EndpointBuilder>>();

            public void Add(Action<EndpointBuilder> convention)
            {
                _actions.Add(convention);
            }

            public void Apply(IEndpointConventionBuilder builder)
            {
                foreach (var a in _actions)
                {
                    builder.Add(a);
                }
            }
        }
    }

    public static class CarterExtensions
    {
        public static IEndpointConventionBuilder MapCarter(this IEndpointRouteBuilder builder)
        {
            var builders = new List<IEndpointConventionBuilder>();

            using var scope = builder.ServiceProvider.CreateScope();
            foreach (var module in scope.ServiceProvider.GetServices<CarterModule>())
            {
                foreach (var route in module.Routes)
                {
                    var conventionBuilder = builder.MapMethods(route.Key.path, new[] { route.Key.verb }, route.Value.handler);
                    route.Value.conventions.Apply(conventionBuilder);
                    builders.Add(conventionBuilder);
                }
            }

            // Allow the user to apply conventions to all modules
            return new CompositeConventionBuilder(builders);
        }

        private class CompositeConventionBuilder : IEndpointConventionBuilder
        {
            private readonly List<IEndpointConventionBuilder> _builders;
            public CompositeConventionBuilder(List<IEndpointConventionBuilder> builders)
            {
                _builders = builders;
            }

            public void Add(Action<EndpointBuilder> convention)
            {
                foreach (var builder in _builders)
                {
                    builder.Add(convention);
                }
            }
        }
    }

    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthorization();
            services.AddScoped<CarterModule, HelloModule>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapCarter();
            });
        }
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Getting Started with ASP.NET CORE Signature Control
This section briefly explains about how to include ASP.NET Core Signature control in your ASP.NET Core application using Visual Studio. Prerequisites. System ...
Read more >
How do I DER encode a signature in .NET Core 3.1?
Hi, I have a requirement for a new integration we are building to sign the contents of the request we send using a...
Read more >
Telerik UI for ASP.NET Core Signature Overview
The Telerik UI for ASP.NET Core Signature enables the user to create handwritten signatures. In this demo, you can test different features such...
Read more >
Using Digital Signatures to check integrity of cipher texts in ...
This post shows how digital signatures can be implemented to check the integrity of cipher texts in ASP.NET Core Razor Pages.
Read more >
Digital signature integration in asp.net core
I have integrated digital signature on a pdf using asp.net core and adobe esign API. So I can sign the agreement via email...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found