【问题标题】:Application Builder Map does not work for middlewaresApplication Builder Map 不适用于中间件
【发布时间】:2019-01-23 20:27:05
【问题描述】:

我遇到以下问题:

我有一个ASP NET Core 应用程序,我正在使用以下路由:
status,
message,
http.
前 2 个接受 websocket 请求。

问题是管道中的AppBuilder.Map 不起作用,它总是将我发送到所有请求的第一个路由。

计划

class Program
{
    static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }
    public static IWebHost BuildWebHost(string[] args)=>

        WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel()
        .UseSockets()
        .UseUrls($"http://0.0.0.0:{Constants.SERVER_PORT}/")
        .Build();
}

启动

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddTransient<StatusService>();//(x => new StatusService());
        services.AddTransient<RegisterService>();
        services.AddTransient<MessagingService>();

        services.AddCors();

    }
    public void Configure(IApplicationBuilder builder)
    {
        builder.UseCors((p) => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());

        builder.UseWebSockets();

        builder.Map("/status", app =>
        {
          builder.UseMiddleware<StatusWare>();
        });
        builder.Map("/http", app =>
        {
           builder.UseMiddleware<HTTPWare>();
        });
        builder.Map("/message", app =>
        {
            builder.UseMiddleware<MessageWare>();
        });
    }
}

中间件都使用他们的特定服务,因为其他两个中间件的Invoke 方法没有被调用,所以我不会发布。

中间件

状态

class StatusWare
{
    StatusService handler;
    public StatusWare(StatusService _handler,RequestDelegate del)
    {
        this.handler = _handler;
        this.next = del;
    }

    RequestDelegate next;

    public async Task Invoke(HttpContext context)
    {

        if (!context.WebSockets.IsWebSocketRequest)
        {
            await  this.next(context);
            return;
        }

        await this.handler.AddClientAsync(context.WebSockets);
    }
}

留言

class MessageWare
{
    private MessagingService messageService;
    private RequestDelegate next;
    public MessageWare(MessagingService serv,RequestDelegate del)
    {
        this.messageService = serv;
        this.next = del;
    }
    public async Task Invoke(HttpContext context)
    {
        if (!context.WebSockets.IsWebSocketRequest)
        {
            await next(context);
        }
        await this.messageService.AcceptClientAsync(context.WebSockets);
    }
}

HTTP

class HTTPWare
{
    RequestDelegate next;
    RegisterService registerService;
    public HTTPWare(RequestDelegate _del,RegisterService service)
    {
        this.next = _del;
        this.registerService = service;
    }
    public async Task Invoke(HttpContext context)
    {

    }
}

如您所见,中间件几乎相同(我没有在 HttpWare 中写任何东西,因为它的 Invoke 方法也没有被调用。

所以我的问题是。为什么尽管使用了AppBuilder.Map,但所有请求都进入第一个中间件StatusWare

会不会是ConfigureServices中添加具体服务的方式?

【问题讨论】:

  • 您使用的地图不正确,请查看文档docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/…
  • 在文档中它与我所做的基本相同。他们将lambda 包装在一个方法中并使用Run 而不是Use。我正在使用Use,因为我可能需要每个分支管道中有更多中间件。
  • 不一样。调用委托处理程序和配置中间件是完全不同的。
  • 您在原始构建器而不是委托参数上调用 UseMiddleware
  • 哦,我现在明白了。所以我需要做的就是使用当前的IAppBuilder?取决于我的嵌套程度?在我的情况下,我会使用 app.UseMiddleware 而不是 builder.UseMiddleware?

标签: c# asp.net-core asp.net-core-middleware


【解决方案1】:

Configure 在原始 builder 上调用 UseMiddleware 而不是在委托参数上。在这种情况下app

更新Map 调用以在构建器委托参数上使用中间件。

public void Configure(IApplicationBuilder builder) {
    builder.UseCors((p) => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());

    builder.UseWebSockets();

    builder.Map("/status", app => {
        app.UseMiddleware<StatusWare>();
    });
    builder.Map("/http", app => {
        app.UseMiddleware<HTTPWare>();
    });
    builder.Map("/message", app => {
        app.UseMiddleware<MessageWare>();
    });
}

参考ASP.NET Core Middleware

【讨论】:

    猜你喜欢
    • 2020-08-21
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多