2017-10-28 74 views
0

我試圖設置路由如下。只有{id}參數的路由返回「無法找到資源」錯誤

現在我的URL看起來像www.mysite.com/Products/index/123

我的目標是建立URL像www.mysite.com/123

其中:產品是我的控制器名稱,索引是我的動作名稱和是可以爲空id參數。

這是我的路線:

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


     routes.MapRoute(
      "OnlyId", 
      "{id}", 
     new { controller = "Products", action = "index", id = UrlParameter.Optional } 

    ); 

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

     ); 


    } 

,這是我的操作方法

public ActionResult index (WrappedViewModels model,int? id) 
    { 

     model.ProductViewModel = db.ProductViewModels.Find(id); 
     model.ProductImagesViewModels = db.ProductImagesViewModels.ToList(); 

     if (id == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(model); 
    } 

這是我的模型的包裝:

public class WrappedViewModels 
{   
    public ProductViewModel ProductViewModel { get; set; }    
    public ProductImagesViewModel ProductImagesViewModel { get; set; } 
    public List<ProductImagesViewModel> ProductImagesViewModels { get; set; 
} 

則拋出Error這個網址:WWW .mysite.com/123

現在的問題是: 爲什麼我的視圖返回這個錯誤以及如何避免這種行爲?

在此先感謝。

+0

你的'WrappedViewModels'定義是怎樣的?這應該很好。你正在嘗試給你404的網址是什麼? – Shyju

+0

嗨。我編輯了我的問題,在此URL上發生錯誤「www.mysite.com/123」 –

+1

您需要包含所有路線,因爲訂單很重要。 –

回答

1

在RegisterRoutes中,您需要指定更多。

routes.MapRoute(
    name: "OnlyId", 
    url: "{id}", 
    defaults: new { controller = "Products", action = "index" }, 
    constraints: new{ id=".+"}); 

,然後你需要指定每個錨標籤的路由作爲

@Html.RouteLink("123", routeName: "OnlyId", routeValues: new { controller = "Products", action = "index", id= "id" }) 

我認爲這將解決你眼前。

0

如果您確信id參數爲空整數值,地點的路線約束與\d正則表達式這樣的,所以它不會影響其他路線:

routes.MapRoute(
    name: "OnlyId", 
    url: "{id}", 
    defaults: new { controller = "Products", action = "index" }, // note that this default doesn't include 'id' parameter 
    constraints: new { id = @"\d+" } 
); 

如果你對標準不滿意參數的限制,您可以創建繼承IRouteConstraint一類,並應用您的自定義路線如下例所示:

// adapted from /a/11911917/ 
public class CustomRouteConstraint : IRouteConstraint 
{ 
    public CustomRouteConstraint(Regex regex) 
    { 
     this.Regex = regex; 
    } 

    public CustomRouteConstraint(string pattern) : this(new Regex("^(" + pattern + ")$", RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.IgnoreCase)) 
    { 
    } 

    public Regex Regex { get; set; } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     if (routeDirection == RouteDirection.IncomingRequest && parameterName == "id") 
     { 
      if (values["id"] == UrlParameter.Optional) 
       return true; 
      if (this.Regex.IsMatch(values["id"].ToString())) 
       return true; 

      // checking if 'id' parameter is exactly valid integer 
      int id; 
      if (int.TryParse(values["id"].ToString(), out id)) 
       return true; 
     } 
     return false; 
    } 
} 

然後將自定義路由約束上id爲基礎的路線,讓其他路線工作:

routes.MapRoute(
    name: "OnlyId", 
    url: "{id}", 
    defaults: new { controller = "Products", action = "index", id = UrlParameter.Optional }, 
    constraints: new CustomRouteConstraint(@"\d*") 
); 
0

我想你錯過了路由順序。因此,創建處理所有可用控制器的第一個路由定義,然後定義一個處理其餘請求的處理器,例如處理請求類型的請求。

所以交換OnlyId默認規則,無需更多的變化。我相信現在應該可以正常工作。