1

我已经使用web api创建了web应用程序。该应用程序包含一些Controllers例如TodoController如何用.NET中的api端点创建中间件核心

namespace TodoApi.Controllers 
{ 
    [Route("api/[controller]")] 
    public class TodoController : Controller 
    { 
     private readonly TodoContext _context; 

     public TodoController(TodoContext context) 
     { 
      _context = context; 
     }  

     [HttpGet] 
     public IEnumerable<TodoItem> GetAll() 
     { 
      return _context.TodoItems.ToList(); 
     } 
    } 
} 

如果我创建了GET要求 - /api/todo - 我得到待办事项从数据库列表中。

我有一个像上面那样的控制器和API端点列表。

我想这个API分发到其他应用程序的理想像中间件 - 我的想法是登记Startup.cs这样的:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddTodoApi(); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    app.UseTodoApi(); 
} 

这将是真棒使用情况我的API,但我不知道该怎么控制器API端点重写像中间件和返回相同的JSON数据相同方法使用经典Controllers

如何在.NET Core中编写middleware以创建API endpoints

回答

3

取而代之的是单独的中间件,可以从另一个组件配置MVC中间件发现控制器:

// using System.Reflection; 

public void ConfigureServices(IServiceCollection services) 
{ 
    ... 
    services 
     .AddMvc() 
     .AddApplicationPart(typeof(TodoController).GetTypeInfo().Assembly); 

控制器是MVC中间件的一部分,他们不是请求管道的一个单独部分(但这是中间件)。当您注册自定义中间件时,默认情况下会调用每个请求,并且您有HttpContext context作为输入参数来处理/编辑 请求/响应数据。但是,ASP.NET Core provides Map* extensions用作分支管道的约定。

Map根据给定请求路径的匹配来分支请求管道。如果请求路径以给定路径开始,则分支被执行。

例子:

private static void HandleMapTodo(IApplicationBuilder app) 
{ 
    app.Run(async context => 
    { 
     await context.Response.WriteAsync("/api/todo was handled"); 
    }); 
} 

public void Configure(IApplicationBuilder app) 
{ 
    app.Map("/api/todo", HandleMapTodo); 
} 

注意,作为中间件一无所知MVC中间件,你只有“原始”的请求访问和没有像模型绑定或MVC行动的过滤器功能。

+0

是否可能teoreticly使用.AddApplicationPart添加一些MVC Razor视图以及?如果是这样,你可以给样品吗? – Jenan

+0

@Jenan没有使用过这个,所以不是100%肯定的,但理论上应该尽可能地发挥你的视图在你的发布输出中的位置。考虑一下,如果你试图找到任何问题与意见...也许要问一个不同的Q ... – Set

+0

是的,你说得对。谢谢。 – Jenan

1

因为它看起来像完美的微服务方法(类似于我的团队现在正在做的),我会创建一个客户端程序集,可以使用您的API,包含您的TodoController的客户端程序集,以及定义合同,以及接口,对于那个API,你可以在其他程序集中注册它,因为它是一个中间件,你也可以在你的单元测试中嘲笑这种行为。

所以,我说,你可以注入在ConfigureServices方法你的客户,你可以创建:

public static IServiceCollection AddTodoRestClient(this IServiceCollection services) 
{ 
    services.AddSingleton<ITodoRestClient, TodoRestClient>(); 
    return services; 
} 

同时认为,你将需要提供enpoint因此,它可能是这样的:

public static IServiceCollection AddConfiguredTodoClient(this IServiceCollection services, string todoEndpoint) 
{ 
    AddTodoClient(services); 
    ITodoRestClient todoRestClient = services.BuildServiceProvider().GetService<ITodoRestClient>(); 
    // Imagine you have a configure method... 
    todoRestClient.Configure(services, todoEndpoint); 
    return services; 
} 

您可以在TodoRestClientInjector类中创建这些方法,并在启动时在Configure方法中使用它们。

我希望它能帮助

---更多的细节,ANSWER评论---

对我来说TodoClient是实现到待办事项API调用REST客户端库,(我已经编辑以前的代码是TodoRestClient)方法,即CreateTodoItem(TodoDto todoItem)实现将调用TodoController.Post([FromBody]项)还是GetTodos(),它将调用TodoController.Get()等,等等... 。

关于enpoints ...这种方法意味着(至少)有两个不同的应用程序(.NET Core应用程序),在一方面是拥有您的TodoController的ASP NET Core应用程序,另一方面是一个控制台应用程序或另一个ASP NET Core API,您将在其上启动类,然后在Rest客户端(Todo Rest客户端)配置上执行启动类...

在微服务的方法使用泊坞窗,在开发环境中,您将使用泊坞窗,撰写-YML,但在传统的方法,你会用实际端口来定义端点...

所以,想象您在第二个服务中需要使用TodoController的控制器来实现,因此我将使用上述方法,并且“SecondController”将如下所示:

public class SecondController : Controller 
    { 
     private readonly SecondContext _context; 
     private readonly TodoRestClient _todoRestClient; 

     public TodoController(SecondContext context, ITodoRestClient todoRestClient) 
     { 
      _context = context; 
      _todoRestClient= todoRestClient; 
     }  

// Whatever logic in this second controller... but the usage would be like: 

_todoRestClient.GetTodos()

} 

只是一些最后提示:这是关键,因为它增加了延迟,而且越来越多,如果这发生在级联,以尽量减少服务之间的调用。另外考虑Docker的使用情况,看起来很具挑战性,但启动起来相当容易,而且实际上,它被认为可以用于您提供的场景和我的解决方案。

再次,我希望它有帮助。

胡安

+0

好的。我很可能会看到这个DI系统方法,但我怎样才能创建特定的API端点?与控制器方法连接在哪里?您能否使用API​​更详细地解释您的想法?什么是TodoClient? – Jenan

+0

当然,我会在最后编辑我的答案...... – Juan

+0

除了我最后的编辑, a)在.NET Core中创建一个REST客户端:https://docs.microsoft.com/en-我们/ dotnet/csharp/tutorials/console-webapiclient b)Polly,NET弹性和瞬态故障处理库:https://github.com/App-vNext/Polly – Juan