2016-05-12 32 views
2

我试图创建一个通用的路线蛞蝓的工作,但我C#泛型的mvc路线总是得到一个错误使用弹头

的想法是,而不是www.site.com/controller/action我在网址友好www.site.com/{slug}

eg www.site.com/Home/Open将代替www.site.com/open-your-company

错误

服务器 '/' 应用程序错误的资源不能发现

在我的Global.asax

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

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

在我的一个cshtml我有以下链接(即使它被评论,仍然有相同的错误)。

@Html.ActionLink("Open your company", "DefaultSlug", new { controller = "Home", action = "Open", slug = "open-your-company" }) 

编辑:HomeController的

public ActionResult Open() { 
    return View(new HomeModel()); 
} 
+0

证明'DefaultSlug'路线图的行动。 – Nkosi

+0

这个动作是在家里打开'public ActionResult Open() { return View(new HomeModel()); }' –

+0

但是我想你有一点,我看到INSIDE的HomeModel中有一些参数是按位置访问的。将现在测试它 –

回答

0

在Global.asax中你slug如果为空,将URL不会去默认路由

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

    routes.MapRoute(
     name: "DefaultSlug", 
     url: "{slug}", 
     defaults: new { controller = "Home", action = "Open" }, 
     constraints: new{ slug=".+"}); 

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

和更新不能为空, HomeController

public ActionResult Open(string slug) { 
    HomeModel model = contentRepository.GetBySlug(slug); 

    return View(model); 
} 

测试路线链接...

@Html.RouteLink("Open your company", routeName: "DefaultSlug", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" }) 

和动作链接...

@Html.ActionLink("Open your company", "Open", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" }) 

都产生......

http://localhost:35979/open-your-company 
+0

仍在测试,但此代码不会创建“控制器/操作?slug”?我试图得到像*** www.site.com/slug***而不是“www.site.com/controller/action” –

+0

然后使用您在您的帖子中的原始动作链接格式,你打电话通过名称'DefaultSlug'的路线 – Nkosi

+0

这是我正在尝试,但似乎没有工作,错误仍然存​​在。任何想法? –

0

这是我走上完成类似任务的步骤。这依靠模型上的自定义Slug字段来匹配路线。

  1. 设置您的控制器例如控制器\ PagesController.cs:

    public class PagesController : Controller 
    { 
        // Regular ID-based routing 
        [Route("pages/{id}")] 
        public ActionResult Detail(int? id) 
        { 
         if(id == null) 
         { 
          return new HttpNotFoundResult(); 
         } 
    
         var model = myContext.Pages.Single(x => x.Id == id); 
         if(model == null) 
         { 
          return new HttpNotFoundResult(); 
         } 
         ViewBag.Title = model.Title; 
         return View(model); 
        } 
    
        // Slug-based routing - reuse View from above controller. 
        public ActionResult DetailSlug (string slug) 
        { 
         var model = MyDbContext.Pages.SingleOrDefault(x => x.Slug == slug); 
         if(model == null) 
         { 
          return new HttpNotFoundResult(); 
         } 
         ViewBag.Title = model.Title; 
         return View("Detail", model); 
        } 
    } 
    
  2. 成立App_Start \ RouteConfig.cs

    路由
    public class RouteConfig 
    { 
        public static void RegisterRoutes(RouteCollection routes) 
        { 
         // Existing route register code 
    
         // Custom route - top priority 
         routes.MapRoute(
           name: "PageSlug", 
           url: "{slug}", 
           defaults: new { controller = "Pages", action = "DetailSlug" }, 
           constraints: new { 
            slug = ".+", // Passthru for no slug (goes to home page) 
            slugMatch = new PageSlugMatch() // Custom constraint 
           } 
          ); 
         } 
    
         // Default MVC route setup & other custom routes 
        } 
    } 
    
  3. 定制IRouteConstraint例如实施utils的\ RouteConstraints.cs

    public class PageSlugMatch : IRouteConstraint 
    { 
        private readonly MyDbContext MyDbContext = new MyDbContext(); 
    
        public bool Match(
         HttpContextBase httpContext, 
         Route route, 
         string parameterName, 
         RouteValueDictionary values, 
         RouteDirection routeDirection 
        ) 
        { 
         var routeSlug = values.ContainsKey("slug") ? (string)values["slug"] : ""; 
         bool slugMatch = false; 
         if (!string.IsNullOrEmpty(routeSlug)) 
         { 
          slugMatch = MyDbContext.Pages.Where(x => x.Slug == routeSlug).Any(); 
         } 
         return slugMatch; 
        } 
    }