2

我怎样才能在 Asp.Net MVC 4 中像这个 url ( http://www.domain.com/friendly-content-title ) 一样。

注意:此参数始终是动态的。URL 可能不同:“friendly-content-title”

我尝试自定义属性,但在 ActionResult 中没有捕捉到这个(友好内容标题)参数。

意见:

  • 主页/索引
  • 主页/视频

行动结果:

    // GET: /Home/        
    public ActionResult Index()
    {
        return View(Latest);
    }

    // GET: /Home/Video        
    public ActionResult Video(string permalink)
    {
        var title = permalink;
        return View();
    }

路由配置:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

        routes.MapRoute(
            name: "Video Page",
            url: "{Home}/{permalink}",
            defaults: new { controller = "Home", action = "Video", permalink = "" }
        );

    }

我应该怎么做才能捕获到 url (/friendly-content-title)?

4

3 回答 3

6

要启用属性路由,请在配置期间调用 MapMvcAttributeRoutes。以下是截取的代码。

     public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
             {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                routes.MapMvcAttributeRoutes();
             }
        }

在 MVC5 中,我们可以将属性路由与基于约定的路由结合起来。以下是截取的代码。

        public static void RegisterRoutes(RouteCollection routes)
         {
          routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
          routes.MapMvcAttributeRoutes();
          routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
       );
  }

通过在路由参数中添加问号可以很容易地使 URI 参数成为可选参数。我们还可以使用参数=值的形式指定默认值。是完整的文章。

于 2014-09-15T07:01:54.123 回答
4

Radim Köhler 的解决方案是一个很好的解决方案。

但是,如果您想对路由进行更多控制,另一种选择是使用自定义约束。

这是一个例子

路由配置.cs

routes.MapRoute(
            "PermaLinkRoute", //name of route
            "{*customRoute}", //url - this pretty much catches everything
            new {controller = "Home", action = "PermaLink", customRoute = UrlParameter.Optional},
            new {customRoute = new PermaLinkRouteConstraint()});

那么在你的家庭控制器上你可以有这样的动作

家庭控制器.cs

public ActionResult PermaLink(string customRoute)
{
    //customRoute would be /friendly-content-title..do what you want with it
}

神奇之处IRouteConstraint在于我们指定为MapRoute调用中的第四个参数。

PermaLinkRouteConstraint.cs

public class PermaLinkRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        var permaRoute = values[parameterName] as string;
        if (permaRoute == null)
            return false;

        if (permaRoute == "friendly-content-title")
            return true; //this indicates we should handle this route with our action specified

        return false; //false means nope, this isn't a route we should handle
    }
}

我只是想展示一个这样的解决方案来展示你基本上可以做任何你想做的事情。

显然,这需要调整。此外,您必须小心不要在Match方法中进行数据库调用或任何缓慢的操作,因为我们将其设置为针对通过您网站的每个请求进行调用(您可以将其移动以按不同顺序调用) .

如果它适合您,我会选择 Radim Köhler 的解决方案。

于 2014-05-25T15:45:07.707 回答
3

我们需要的是一些标记关键字。明确地说应该将 url 视为动态的,使用friendly-content-title. 我建议使用关键字video,然后这将是路由的映射:

routes.MapRoute(
    name: "VideoPage",
    url: "video/{permalink}",
    defaults: new { controller = "Home", action = "Video", permalink = "" }
);
routes.MapRoute(
    name: "HomePage",
    url: "{controller}/{action}",
    defaults: new { controller = "Home", action = "Index" }
);

现在,因为VideoPage被声明为第一个,所有的 url (如下所示)都将被视为动态的:

// these will be processed by Video action of the Home controller
domain/video/friendly-content-title 
domain/video/friendly-content-title2 

而任何其他 ( controllerName/ActionName) 将以标准方式处理

于 2014-05-25T14:35:45.553 回答