ASP.net MVC支持带有连字符的URL

Joh*_*ohn 31 url asp.net-mvc seo url-routing

有一种简单的方法可以让MvcRouteHandler将传入URL的操作和控制器部分中的所有连字符转换为下划线,因为方法或类名称不支持连字符.

这样我就可以支持像sample.com/test-page/edit-details这样的结构映射到Action edit_details和Controller test_pagecontroller,同时继续使用MapRoute方法.

我知道我可以指定一个动作名称属性并支持控制器名称中的连字符,这些连字符可以手动添加路由来实现这一点,但是我正在寻找一种自动化方式,以便在添加新控制器和操作时节省错误.

And*_*rew 32

对于喜欢它的人来说,John的帖子的C#版本:我博客上的C#和VB版本

public class HyphenatedRouteHandler : MvcRouteHandler{
        protected override IHttpHandler  GetHttpHandler(RequestContext requestContext)
        {
            requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
            requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");
            return base.GetHttpHandler(requestContext);
        }
    }
Run Code Online (Sandbox Code Playgroud)

......和新路线:

routes.Add(
            new Route("{controller}/{action}/{id}", 
                new RouteValueDictionary(
                    new { controller = "Default", action = "Index", id = "" }),
                    new HyphenatedRouteHandler())
        );
Run Code Online (Sandbox Code Playgroud)

您也可以使用以下方法,但请记住,如果您希望让visual studio自动生成您的视图文件,您需要将视图命名为My-Action,这可能很烦人.

[ActionName("My-Action")]
public ActionResult MyAction() {
    return View();
}
Run Code Online (Sandbox Code Playgroud)

  • 您如何使用@ Html.Actionlink指向连字符网址?@ Html.ActionLink("Test","Action","ControllerName-Hyphen")在上面的例子中,actionlink不知道如何处理连字符,我必须创建另一个扩展名,用""替换" - " ?我希望生成的url在那里有连字符 (2认同)

Joh*_*ohn 18

我找到了解决方案.MvcRouteHandler中的requestContext包含控制器和操作的值,您可以在其上进行简单替换.

Public Class HyphenatedRouteHandler
    Inherits MvcRouteHandler

    Protected Overrides Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) As System.Web.IHttpHandler
        requestContext.RouteData.Values("controller") = requestContext.RouteData.Values("controller").ToString.Replace("-", "_")
        requestContext.RouteData.Values("action") = requestContext.RouteData.Values("action").ToString.Replace("-", "_")
        Return MyBase.GetHttpHandler(requestContext)
    End Function

End Class
Run Code Online (Sandbox Code Playgroud)

然后你需要用等效的routes.Add替换routes.MapRoute,指定新的路由处理程序.这是必需的,因为MapRoute不允许您指定自定义路由处理程序.

routes.Add(New Route("{controller}/{action}/{id}", New RouteValueDictionary(New With {.controller = "Home", .action = "Index", .id = ""}), New HyphenatedRouteHandler()))
Run Code Online (Sandbox Code Playgroud)


Chr*_*way 14

在这种情况下,您真正​​需要做的就是使用连字符命名您的视图,因为您希望它出现在URL中,删除控制器中的连字符,然后添加一个带有连字符的ActionName属性.根本不需要下划线.

有一个名为edit-details.aspx的视图

并有一个像这样的控制器:

[ActionName("edit-details")]
public ActionResult EditDetails(int id)
{
    // your code
}
Run Code Online (Sandbox Code Playgroud)


dst*_*nol 9

我意识到这是一个相当古老的问题,但对我来说,这只是接受带有连字符的url的故事的一半,另一半是生成这些URL同时仍然能够在MVC框架中使用Html.ActionLink和其他帮助程序,我通过创建类似的自定义路由类解决了这个问题,这里的代码是为了帮助任何人从谷歌搜索来到这里.它还包括网址的下部外壳.

public class SeoFriendlyRoute : Route
{
     // constructor overrides from Route go here, there is 4 of them

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

          if (path != null)
          {
              var indexes = new List<int>();
              var charArray = path.VirtualPath.Split('?')[0].ToCharArray();
              for (int index = 0; index < charArray.Length; index++)
              {
                  var c = charArray[index];
                  if (index > 0 && char.IsUpper(c) && charArray[index - 1] != '/')
                      indexes.Add(index);
              }

              indexes.Reverse();
              indexes.Remove(0);
              foreach (var index in indexes)
                  path.VirtualPath = path.VirtualPath.Insert(index, "-");

              path.VirtualPath = path.VirtualPath.ToLowerInvariant();
          }

          return path;
     }
}
Run Code Online (Sandbox Code Playgroud)

然后在添加路由时,您可以创建RouteCollection扩展,也可以在全局路由声明中使用以下内容

routes.Add(
        new SeoFriendlyRoute("{controller}/{action}/{id}", 
            new RouteValueDictionary(
                new { controller = "Default", action = "Index", id = "" }),
                new HyphenatedRouteHandler())
    );
Run Code Online (Sandbox Code Playgroud)