如何在ASP.NET Core中忽略路由?

20

以前我们会将类似下面的代码添加到 Global.aspx.cs 中,但在 .NET Core 中已经不存在了:

  routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

以下是我目前在我的Startup.cs中使用的代码(针对 .NET Core):

  app.UseDefaultFiles();

  app.UseStaticFiles();

  app.UseMvc(routes =>
  {
      routes.MapRoute(
          name: "default",
          template: "{controller=Home}/{action=Index}/{id?}");

      routes.MapSpaFallbackRoute(
          name: "spa-fallback",
          defaults: new { controller = "Home", action = "Index" });
  });

问题在于在MVC(在Core版之前)routes是一个RouteCollection,而在.NET Core中它是一个Microsoft.AspNetCore.Routing.IRouteBuilder,因此IgnoreRoute不是有效的方法。

6个回答

19

你可以为此编写中间件

public void Configure(IApplciationBuilder app) {
    app.UseDefaultFiles();

    // Make sure your middleware is before whatever handles 
    // the resource currently, be it MVC, static resources, etc.
    app.UseMiddleware<IgnoreRouteMiddleware>();

    app.UseStaticFiles();
    app.UseMvc();
}

public class IgnoreRouteMiddleware {

    private readonly RequestDelegate next;

    // You can inject a dependency here that gives you access
    // to your ignored route configuration.
    public IgnoreRouteMiddleware(RequestDelegate next) {
        this.next = next;
    }

    public async Task Invoke(HttpContext context) {
        if (context.Request.Path.HasValue &&
            context.Request.Path.Value.Contains("favicon.ico")) {

            context.Response.StatusCode = 404;

            Console.WriteLine("Ignored!");

            return;
        }

        await next.Invoke(context);
    }
}

6
非常感谢您的留言。简而言之,我必须用一个完整的自定义路由替换一行代码? 这似乎有些臃肿。 - Jeff Guillaume
1
也许?在.NET Core中可能有一种更直接解决您问题的方法。也许是通过Routing中间件。我只是没有遇到过。我建议阅读此文档,然后查看源代码以获得更明确的内容:https://docs.asp.net/en/latest/fundamentals/routing.html - Technetium
1
这个解决方案是有道理的,但应该更具体化。寻找包含所提供字符串的路径意味着可能会匹配到不想匹配的路径,这也不是非常理想的。从性能角度考虑,最好不要使用中间件并将路由数量保持在最少。 - Professor of programming
为解决Bonner的担忧,应该使用StartsWith("/favicon.ico")来替换Contains(...)。除此之外,这是一个优秀的回答。 - Alexei - check Codidact
这个可行,但请见下面我的答案以获取更简单的解决方案。 - Jess

9

.NET Core 3.1

对于使用端点路由的.NET Core 3.1,这似乎是最简单的方法。您无需为这种简单情况构建中间件。

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/favicon.ico", async (context) =>
    {
        context.Response.StatusCode = 404;
    });
    // more routing
});

原问题是关于忽略路由的。如果要提供网站图标,可以在_Layout.cshtml中添加HTML标记,就像这样。这种技术允许更好的控制图标的来源位置。
<link rel="icon" href="@Url.Content("~/images/favicon.ico")" />

我在我的代码中同时使用了这两种技术。


2
啊,很高兴看到这个变得更好了! - Technetium
但目标不是返回404错误,而是实际的favicon.ico文件。 - Jeff Guillaume
1
请查看我的新编辑 @JeffGuillaume - Jess

8
如果您想让静态文件在没有路由条件的情况下可访问,只需使用内置的 StaticFiles Middleware。在 Configure 方法中使用 app.UseStaticFiles(); 来激活它,并将您的静态文件放在 wwwroot 目录中。它们可以通过 HOST/yourStaticFile 访问。
更多信息请参见此处

5
public void Configure 函数内部添加:
app.Map("/favicon.ico", delegate { });

1
如果您正在使用Swagger并且希望忽略控制器(仍需要此答案),还可以添加[ApiExplorerSettings(IgnoreApi = true)],这将从Swagger文档中删除。 - Adam Cox
这个答案是可行的,但在.NET Core 3.1中会抛出一个异常System.InvalidOperationException: The request reached the end of the pipeline without executing the endpoint: '/favicon.ico HTTP: GET'. Please register the EndpointMiddleware using 'IApplicationBuilder.UseEndpoints(...)' if using routing. - Jess
@Jess 很好知道。原始答案是针对 .NET Core 1.0.1 的。 - Zam

3
允许路由处理程序解析favicon请求,并将您的路由保持最少。避免使用中间件,这只会给您的代码增加额外的复杂性,并意味着所有其他请求都必须在路由处理程序之前通过中间件,这对于繁忙的网站来说性能更差。对于不繁忙的网站,您只是在浪费时间担心这个问题。
请参见https://github.com/aspnet/Routing/issues/207

0
在ASP.NET Core中,您可以编写一个受限制的catch-all路由模板。为此,在您的ASP.NET Core示例中,将调用routes.MapSpaFallbackRoute替换为以下内容:
// Returns the home/index page for unknown files, except for
// favicon.ico, in which case a 404 error is returned.
routes.MapRoute(
    name: "spa-fallback",
    template: "{*url:regex(^(?!favicon.ico).*$)}",
    defaults: new { Controller = "Home", action = "Index" });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接