我有两种冲突的操作方法。基本上,我希望能够使用两条不同的路线(通过项的ID或项的名称及其父项(在不同的父项中,项可以具有相同的名称))进入同一视图。搜索词可用于过滤列表。
例如…
Items/{action}/ParentName/ItemName Items/{action}/1234-4321-1234-4321
这是我的动作方法(也有Remove动作方法)…
Remove
// Method #1 public ActionResult Assign(string parentName, string itemName) { // Logic to retrieve item's ID here... string itemId = ...; return RedirectToAction("Assign", "Items", new { itemId }); } // Method #2 public ActionResult Assign(string itemId, string searchTerm, int? page) { ... }
这是路线…
routes.MapRoute("AssignRemove", "Items/{action}/{itemId}", new { controller = "Items" } ); routes.MapRoute("AssignRemovePretty", "Items/{action}/{parentName}/{itemName}", new { controller = "Items" } );
我理解为什么会发生错误,因为page参数可以为null,但是我无法找出解决此问题的最佳方法。一开始我的设计不好吗?我曾考虑过将`Method
page
的签名扩展为包括搜索参数,并将逻辑
任何帮助将不胜感激。
实际解决方案 (基于李维斯的答案)
我添加了以下课程…
public class RequireRouteValuesAttribute : ActionMethodSelectorAttribute { public RequireRouteValuesAttribute(string[] valueNames) { ValueNames = valueNames; } public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { bool contains = false; foreach (var value in ValueNames) { contains = controllerContext.RequestContext.RouteData.Values.ContainsKey(value); if (!contains) break; } return contains; } public string[] ValueNames { get; private set; } }
然后修饰动作方法…
[RequireRouteValues(new[] { "parentName", "itemName" })] public ActionResult Assign(string parentName, string itemName) { ... } [RequireRouteValues(new[] { "itemId" })] public ActionResult Assign(string itemId) { ... }
MVC不支持仅基于签名的方法重载,因此将失败:
public ActionResult MyMethod(int someInt) { /* ... */ } public ActionResult MyMethod(string someString) { /* ... */ }
但是,它 确实 支持基于属性的方法重载:
[RequireRequestValue("someInt")] public ActionResult MyMethod(int someInt) { /* ... */ } [RequireRequestValue("someString")] public ActionResult MyMethod(string someString) { /* ... */ } public class RequireRequestValueAttribute : ActionMethodSelectorAttribute { public RequireRequestValueAttribute(string valueName) { ValueName = valueName; } public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { return (controllerContext.HttpContext.Request[ValueName] != null); } public string ValueName { get; private set; } }
在上面的示例中,该属性只说“如果请求中存在键 xxx, 则此方法匹配”。如果更适合您的目的,您还可以按路由(controllerContext.RequestContext)中包含的信息进行筛选。