只有{id}参数的路由返回“无法找到资源”错误
问题描述:
我试图设置路由如下。只有{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
现在的问题是: 为什么我的视图返回这个错误以及如何避免这种行为?
在此先感谢。
答
在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" })
我认为这将解决你眼前。
答
如果您确信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*")
);
答
我想你错过了路由顺序。因此,创建处理所有可用控制器的第一个路由定义,然后定义一个处理其余请求的处理器,例如处理请求类型的请求。
所以交换的OnlyId和默认规则,无需更多的变化。我相信现在应该可以正常工作。
你的'WrappedViewModels'定义是怎样的?这应该很好。你正在尝试给你404的网址是什么? – Shyju
嗨。我编辑了我的问题,在此URL上发生错误“www.mysite.com/123” –
您需要包含所有路线,因为订单很重要。 –