2009-09-06 1 views
28

У меня здесь небольшая проблема. Мне нужно добавить конечную косую черту в конце каждого URL-адреса на сайте, над которым я работаю. Я определил все ссылки внутри сайта, чтобы иметь косую черту, как так:
Добавить конечную косую черту в конце каждого URL-адреса?

<a href="/register/">Register</a> 

В то время как это работает отлично, есть еще одна крошечная проблема: это с сгенерированным URL'о, которые приходят от вызова RedirectToAction(). Например:

return RedirectToAction("Register", "Users"); 

Вызовет URL-адрес, чтобы изменить/зарегистрироваться не слэш. Я изменил свою систему маршрутизации таким образом:

routes.MapRoute("register", 
         "register/", 
         new {controller = "Users", action = "Register"} 
      ); 

Тем не менее требуется завершающий слэш не добавляется автоматически!
Я искал этот номер question и этот question, но они совершенно разные, поскольку я не использую библиотеки перезаписи url, я просто использую asp.net mvc routing system.
Итак, что вы скажете, ребята?

+0

Для всех, кто интересуется, как это сделать для ASP.NET Core, используйте 'services.Configure (routeOptions => {routeOptions.AppendTrailingSlash = true;};' где 'services' является' IServiceCollection' – Galilyou

ответ

46

Класс RouteCollection теперь имеет логическое выражение AppendTrailingSlash, для которого вы можете установить значение true.

+0

Большое спасибо. Это лучшее решение для меня. – Stuart

+1

Отметьте этот ответ как правильный, пожалуйста, –

+0

Нет, не работает с MVC4. – RoninCoder

21

Вы можете создать новый маршрут, который переопределяет метод GetVirtualPath. В этом методе вы добавляете конечную косую черту в VirtualPath. Как это:

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
{ 
    VirtualPathData path = base.GetVirtualPath(requestContext, values); 

    if (path != null) 
     path.VirtualPath = path.VirtualPath + "/"; 
    return path; 
} 

Для краткости я отправил whole example on CodePaste.net

Теперь все, что вам нужно сделать, это зарегистрировать маршруты с routes.MapRouteTrailingSlash() вместо routes.MapRoute().

routes.MapRouteTrailingSlash("register", 
          "register", 
          new {controller = "Users", action = "Register"} 
); 

Маршрут будет затем добавить косую черту в пути, когда GetVirtualPath() называется. Которое будет делать RedirectToAction().

Update: Поскольку ссылка CodePaste вниз, вот полный код:

public class TrailingSlashRoute : Route { 
    public TrailingSlashRoute(string url, IRouteHandler routeHandler) 
     : base(url, routeHandler) {} 

    public TrailingSlashRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) 
     : base(url, defaults, routeHandler) {} 

    public TrailingSlashRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, 
          IRouteHandler routeHandler) 
     : base(url, defaults, constraints, routeHandler) {} 

    public TrailingSlashRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, 
          RouteValueDictionary dataTokens, IRouteHandler routeHandler) 
     : base(url, defaults, constraints, dataTokens, routeHandler) {} 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { 
     VirtualPathData path = base.GetVirtualPath(requestContext, values); 

     if (path != null) 
      path.VirtualPath = path.VirtualPath + "/"; 
     return path; 
    } 
} 

public static class RouteCollectionExtensions { 
    public static void MapRouteTrailingSlash(this RouteCollection routes, string name, string url, object defaults) { 
     routes.MapRouteTrailingSlash(name, url, defaults, null); 
    } 

    public static void MapRouteTrailingSlash(this RouteCollection routes, string name, string url, object defaults, 
             object constraints) { 
     if (routes == null) 
      throw new ArgumentNullException("routes"); 

     if (url == null) 
      throw new ArgumentNullException("url"); 

     var route = new TrailingSlashRoute(url, new MvcRouteHandler()) 
        { 
         Defaults = new RouteValueDictionary(defaults), 
         Constraints = new RouteValueDictionary(constraints) 
        }; 

     if (String.IsNullOrEmpty(name)) 
      routes.Add(route); 
     else 
      routes.Add(name, route); 
    } 
} 
+0

Спасибо Manticore , будет проверять. – Galilyou

+0

CodePaste.net Неисправна ссылка – John

+0

Хотелось бы увидеть весь пример кода, который вы упомянули. К сожалению, ваша ссылка не работает :(Если бы у вас была возможность предоставить альтернативную ссылку, чтобы я мог видеть ваш пример кода, пожалуйста, – marcusstarnes

5

Хороший чистый раствор, codingbug !!

Единственная проблема, с которой я столкнулся, была двойная косая черта для главной страницы MVC3.

Бритва пример:

@Html.ActionLink("Home", "Index", "Home") 

Связанный:
http://mysite.com//

Чтобы это исправить, я подправил GetVirtualPath переопределения:

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
{  
    VirtualPathData path = base.GetVirtualPath(requestContext, values);  

    if (path != null && path.VirtualPath != "")  
     path.VirtualPath = path.VirtualPath + "/";  
    return path;  
} 
3

выше решения по codingbug очень приятно. Мне нужно было что-то очень симулятивное, но только для моего корневого URL. Я знаю, что с этим возникают проблемы, но вот что я сделал. Кажется, это прекрасно работает во всех моих условиях. Я думаю, что это тоже работает, потому что это только наша домашняя страница, когда они впервые приходят и у меня нет тренировочной косой черты. Это тот случай, который я пытался избежать. Если это то, чего вы хотите избежать, это сработает для вас.

public class HomeController : Controller 
    { 
    public ActionResult Index() 
    { 
     if (!Request.RawUrl.Contains("Index") && !Request.RawUrl.EndsWith("/")) 
     return RedirectToAction("Index", "Home", new { Area = "" }); 

Если выяснится, мне нужно больше загара. Я, вероятно, буду использовать код, предоставленный codingbug. До тех пор мне нравится держать его простым.

Примечание: Я рассчитываю, что Home \ Index будет удален из URL-адреса с помощью механизма маршрутизации.

1

Я знаю, что есть более верные ответы, но лучший проголосовавший ответ не сработал для моего дела. Мне нужно сказать, что я нашел гораздо более легкое решение.

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

Это будет вестись косой чертой «/» во всех случаях.

+1

Нет, не будет. Если это так, а затем вы генерируете url, используя RouteUrl («{имя маршрута»}, новый RouteValueDictionary ({parameters})), конечная косая черта отключается. – Przemo

0

Есть несколько действительно хороших ответов, но вот какой-то код контроллера MVC, как я его реализую в очень простой get.

public ActionResult Orders() 
    { 
     if (!Request.Path.EndsWith("/")) 
     { 
      return RedirectPermanent(Request.Url.ToString() + "/"); 
     } 
     return View(); 
    } 

Надеюсь, это поможет кому-то.