如何从 UseStatusCodePagesWithReExecute 中排除某些路由?

Posted

技术标签:

【中文标题】如何从 UseStatusCodePagesWithReExecute 中排除某些路由?【英文标题】:How can I exclude some routes from UseStatusCodePagesWithReExecute? 【发布时间】:2021-07-02 12:37:06 【问题描述】:

我在 ASP.NET Core 5 中有一个全栈应用程序。前端是 React,后端是 OData。

我需要在我的Configure() 方法中使用app.UseStatusCodePagesWithReExecute("/"); 将任何未知请求重定向到index.html,因为路由是由客户端代码处理的。

问题是在OData标准中,当GET请求中的key无效时,会返回404错误。此错误也会导致重定向到index.html

我的问题:如何从UseStatusCodePagesWithReExecute() 中排除任何以/odata.svc 开头的请求?

// 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();
                

    // generated swagger json and swagger ui middleware
    // You can access the swagger ui at /swagger/index.html 
    app.UseSwagger();
    app.UseSwaggerUI(x => x.SwaggerEndpoint("/swagger/v1/swagger.json", "ASP.NET Core Sign-up and Verification API"));

    //app.UseCors("CorsPolicy");
    // global cors policy
    app.UseCors(x => x
        .SetIsOriginAllowed(origin => true)
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());

    app.UseForwardedHeaders(new ForwardedHeadersOptions
    
        ForwardedHeaders = ForwardedHeaders.All
    );

    app.UseRouting();

    // global error handler
    app.UseMiddleware<ErrorHandlerMiddleware>();

    // custom jwt auth middleware
    app.UseMiddleware<JwtMiddleware>();

    app.UseEndpoints(endpoints =>
    
        endpoints.Select().Expand().Filter().OrderBy().Count().MaxTop(30);
        // add an endpoint for an actual domain model
        // registered this endpoint with name odata (first parameter) 
        // and also with the same prefix (second parameter)
        // in this route, we are returning an EDM Data Model
        endpoints.MapODataRoute("odata.svc", "odata.svc", GetEdmModel(app.ApplicationServices));
        endpoints.EnableDependencyInjection();
        endpoints.MapControllers();
        // enable serving static files
        endpoints.MapDefaultControllerRoute();
    );

    // Redirects any unknown requests to index.html
    app.UseStatusCodePagesWithReExecute("/");

    app.UseHttpsRedirection();

    // Serve default documents (i.e. index.html)
    app.UseDefaultFiles();

    //Set HTTP response headers
    const string cacheMaxAge = "1";
    // Serve static files
    app.UseStaticFiles(new StaticFileOptions
    
        OnPrepareResponse = ctx =>
        
            // using Microsoft.AspNetCore.Http;
            ctx.Context.Response.Headers.Append(
                    "Cache-Control", $"public, max-age=cacheMaxAge");
        
    );

【问题讨论】:

【参考方案1】:

这似乎是UseWhen() extension method 的理想用例。这个功能是(under)documented by Microsoft,尽管@Paul Hiles 在他的DevTrends 博客上有a more comprehensive write-up。基本上,这允许您有条件地将中间件注入到您的执行管道中。

因此,如果您的请求路径以 /odata.svc 开头,要有条件地排除 UseStatusCodePagesWithReExecute(),您只需使用 UseWhen() 条件包装您的 UseStatusCodePagesWithReExecute() 调用,如下所示:

app.UseWhen(
    context => context.Request.Path.StartsWithSegments("/odata.svc"), 
    appBuilder =>
    
        appBuilder.UseStatusCodePagesWithReExecute("/");
    
);

【讨论】:

请注意,您必须在 lambda 的输入参数 appBuilder 上调用方法 UseStatusCodePagesWithReExecute,而不是在 app 上。在 app.UseWhen 中包装现有呼叫时很容易犯错误。至少,我做到了。

以上是关于如何从 UseStatusCodePagesWithReExecute 中排除某些路由?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数

如何从 Firebase 获取所有设备令牌?

如何直接从类调用从接口继承的方法?

如何从服务器获取和设置 android 中的 API(从服务器获取 int 值)?如何绑定和实现这个

如何从Mac从android studio中的fabric注销? [复制]

如何从设备中获取 PDF 文件以便能够从我的应用程序中上传?