Tôi có hai phương pháp hành động mâu thuẫn. Về cơ bản, tôi muốn có thể có cùng một chế độ xem bằng hai tuyến đường khác nhau, bằng ID của một mặt hàng hoặc theo tên của mặt hàng đó và cha mẹ của nó (các mặt hàng có thể có cùng tên giữa các cha mẹ khác nhau). Một thuật ngữ tìm kiếm có thể được sử dụng để lọc danh sách.
Ví dụ...
Items/{action}/ParentName/ItemName
Items/{action}/1234-4321-1234-4321
Đây là phương thức hành động của tôi (cũng có Remove
phương thức hành động) ...
// 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) { ... }
Và đây là các tuyến đường ...
routes.MapRoute("AssignRemove",
"Items/{action}/{itemId}",
new { controller = "Items" }
);
routes.MapRoute("AssignRemovePretty",
"Items/{action}/{parentName}/{itemName}",
new { controller = "Items" }
);
Tôi hiểu tại sao xảy ra lỗi, vì page
tham số có thể là null, nhưng tôi không thể tìm ra cách tốt nhất để giải quyết nó. Là thiết kế của tôi kém để bắt đầu? Tôi đã nghĩ về việc mở rộng Method #1
chữ ký của mình để bao gồm các tham số tìm kiếm và chuyển logic Method #2
ra một phương thức riêng mà cả hai sẽ gọi, nhưng tôi không tin rằng điều đó thực sự sẽ giải quyết sự mơ hồ.
Mọi sự trợ giúp sẽ rất được trân trọng.
Giải pháp thực tế (dựa trên câu trả lời của Levi)
Tôi đã thêm lớp sau ...
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; }
}
Và sau đó trang trí các phương thức hành động ...
[RequireRouteValues(new[] { "parentName", "itemName" })]
public ActionResult Assign(string parentName, string itemName) { ... }
[RequireRouteValues(new[] { "itemId" })]
public ActionResult Assign(string itemId) { ... }
return ValueNames.All(v => controllerContext.RequestContext.RouteData.Values.ContainsKey(v));
contains = ...
phần đó cho một cái gì đó như thế này:contains = controllerContext.RequestContext.RouteData.Values.ContainsKey(value) || controllerContext.RequestContext.HttpContext.Request.Params.AllKeys.Contains(value);
ActionResult DoSomething(Person p)
, nơi Person
có các thuộc tính đơn giản khác nhau Name
và các yêu cầu đối với nó được thực hiện với tên thuộc tính trực tiếp (ví dụ /dosomething/?name=joe+someone&other=properties
:).
controllerContext.HttpContext.Request[value] != null
thay vì controllerContext.RequestContext.RouteData.Values.ContainsKey(value)
; nhưng dù sao cũng là một tác phẩm hay