Routes.AppendTrailingSlash 排除某些路由。

11
在 MVC 5.2.2 中,我可以将 Routes.AppendTrailingSlash 设置为 true,以便在 URL 后添加尾随斜杠。但是,我还有一个返回 robots.txt 内容的 robots 控制器。如何防止 Slash 被附加到 robots.txt 路由,并使其可在没有尾随斜杠的情况下被调用?我的控制器代码:
[Route("robots.txt")]
public async Task<ActionResult> Robots()
{
  string robots = getRobotsContent();
  return Content(robots, "text/plain");
}

我的路由配置看起来像这样:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home",
                                action = "Index",
                                id = UrlParameter.Optional }
            );

RouteTable.Routes.AppendTrailingSlash = true;

1
我有完全相同的问题,除此之外,我的问题还出现在sitemap.xml和opensearch.xml上。你可以在这里看到我的代码。我会为这个问题添加赏金。 - Muhammad Rehan Saeed
2个回答

11

那么使用一个“Action Filter”如何?我快速编写了这个过滤器,并未考虑效率。我已经对手动添加前导“/”的URL进行了测试,结果非常好。

    public class NoSlash : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            var originalUrl = filterContext.HttpContext.Request.Url.ToString();
            var newUrl = originalUrl.TrimEnd('/');
            if (originalUrl.Length != newUrl.Length)
                filterContext.HttpContext.Response.Redirect(newUrl);
        }

    }

尝试以这种方式使用它

   [NoSlash]
   [Route("robots.txt")]
   public async Task<ActionResult> Robots()
   {
       string robots = getRobotsContent();
       return Content(robots, "text/plain");
    }

2
不错的解决方案,我没有想到。 - Boas Enkler

2
如果您导航到一个静态的.txt文件,ASP.NET的行为是在URL有斜杠的情况下返回404未找到页面。
我采用了@Dave Alperovich的方法(谢谢!),而不是重定向到没有尾随斜杠的URL。我认为这两种方法都是完全有效的。
/// <summary>
/// Requires that a HTTP request does not contain a trailing slash. If it does, return a 404 Not Found.
/// This is useful if you are dynamically generating something which acts like it's a file on the web server.
/// E.g. /Robots.txt/ should not have a trailing slash and should be /Robots.txt.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class NoTrailingSlashAttribute : FilterAttribute, IAuthorizationFilter
{
    /// <summary>
    /// Determines whether a request contains a trailing slash and, if it does, calls the <see cref="HandleTrailingSlashRequest"/> method.
    /// </summary>
    /// <param name="filterContext">An object that encapsulates information that is required in order to use the <see cref="System.Web.Mvc.RequireHttpsAttribute"/> attribute.</param>
    /// <exception cref="System.ArgumentNullException">The filterContext parameter is null.</exception>
    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        string url = filterContext.HttpContext.Request.Url.ToString();
        if (url[url.Length - 1] == '/')
        {
            this.HandleTrailingSlashRequest(filterContext);
        }
    }

    /// <summary>
    /// Handles HTTP requests that have a trailing slash but are not meant to.
    /// </summary>
    /// <param name="filterContext">An object that encapsulates information that is required in order to use the <see cref="System.Web.Mvc.RequireHttpsAttribute"/> attribute.</param>
    protected virtual void HandleTrailingSlashRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new HttpNotFoundResult();
    }
}

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