2017-10-28 47 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默认规则,无需更多的变化。我相信现在应该可以正常工作。