2014-09-16 5 views
11

В MVC 5.2.2 Я могу установить Routes.AppendTrailingSlash в true, чтобы конечная косая черта была добавлена ​​к URL-адресам.Routes.AppendTrailingSlash исключает некоторые маршруты

Однако у меня также есть контроллер роботов, который возвращает содержимое для файла robots.txt.

Как я могу предотвратить добавление Slash к маршруту robots.txt и вызвать ли его с помощью косой черты?

код My Controller:

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

My Route Config выглядит следующим образом:

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. Вы можете увидеть мой код [здесь] (https://github.com/RehanSaeed/ASP.NET-MVC-Boilerplate). Я добавлю щедрость на этот вопрос. –

ответ

10

Как насчет действий фильтра. Я написал это быстро, а не для эффективности. Я проверил его по 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

приятное решение не думал об этом –

2

Если перейти в статический файл .txt, поведение в ASP.NET является возвращать 404 Not Found, если URL имеет слэш.

Я принял подход @Dave Alperovich (Спасибо!) И вернул HttpNotFoundResult вместо перенаправления на 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(); 
    } 
} 
Смежные вопросы