Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在.NETCore中创建具有api端点的中间件_Api_Asp.net Core_Middleware_Asp.net Core Webapi_Asp.net Core Middleware - Fatal编程技术网

如何在.NETCore中创建具有api端点的中间件

如何在.NETCore中创建具有api端点的中间件,api,asp.net-core,middleware,asp.net-core-webapi,asp.net-core-middleware,Api,Asp.net Core,Middleware,Asp.net Core Webapi,Asp.net Core Middleware,我已经用web api创建了web应用程序。该应用程序包含一些控制器,例如TodoController: namespace TodoApi.Controllers { [Route("api/[controller]")] public class TodoController : Controller { private readonly TodoContext _context; public TodoController(Todo

我已经用web api创建了web应用程序。该应用程序包含一些
控制器
,例如
TodoController

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();
        }
    }
}
对于我的api来说,这将是一个非常棒的用例,但我不知道这个控制器api端点如何像中间件一样重写,如何像使用经典的
控制器那样返回相同的JSON数据


如何在
.NET Core
中编写
中间件
以创建
API端点

您可以将MVC中间件配置为从另一个程序集发现控制器,而不是单独的中间件:

// using System.Reflection;

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

控制器是MVC中间件的一部分,它们不是请求管道的独立部分(但这就是中间件)。注册自定义中间件时,默认情况下,它会在每个请求上调用,并且您将
HttpContext
作为输入参数来使用/编辑 请求/响应数据。但是ASP.NET内核被用作管道分支的约定

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

例如:

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操作过滤器之类的功能。

因为它看起来像是完美的微服务方法(类似于我的团队现在正在做的),所以我会创建一个可以使用您的API的客户端程序集,如果您为该API定义了契约和接口,则包含TodoController的那个API可以在另一个程序集中注册,因为它是midleware,并且您还可以在单元测试中模拟该行为

所以,正如我所说,您可以在ConfigureServices方法中注入您的客户机,您可以创建:

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

最后几点提示:减少服务之间的调用是关键,因为这会增加延迟,如果这种情况发生在级联上,会越来越多。也可以考虑使用DOCKER,看起来很有挑战性,但它很容易启动,事实上,它被认为是在你所提出的方案和我的解决方案中使用的。 同样,我希望这能有所帮助


胡安

好的。我可能看到这种DI系统方法,但如何创建特定的api端点?何处连接控制器方法?你能详细解释一下你使用API的想法吗?什么是TodoClient?除了我上次编辑的内容外,a)在.NET Core中创建REST客户端:b)Polly,一个网络弹性和瞬时故障处理库:是否可以专门使用.AddApplicationPart添加一些MVC Razor视图?如果是,你能给出一个例子吗?@Jenan没有使用这个,所以不是100%确定,但在理论上,只要你在发布的输出中有正确的视图,这应该是可行的。如果你试着发现任何问题,可以考虑问一个不同的Q…
public static IServiceCollection AddTodoRestClient(this IServiceCollection services)
{
    services.AddSingleton<ITodoRestClient, TodoRestClient>();
    return services;
}
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;
}
  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:
}