2016-05-12 46 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; 
        } 
    }