Lựa chọn 1
Tất nhiên bạn luôn có thể chọn con đường/xe/search /? Nhà cung cấp = Toyota & color = Red & mô hình = Corola và tôi nghĩ rằng nó sẽ tốt cho bạn .
routes.MapRoute(
"CarSearch",
"car/search",
new { controller = "car", action = "search" }
);
Bạn có thể nhận thông số từ Yêu cầu.Params đang hoạt động trong trường hợp này.
Lựa chọn 2
Hoặc bạn có thể xác định params trong bảng định tuyến, nhưng AFAIK nó sẽ được yêu cầu để thực hiện một bộ quy tắc cho tất cả các kết hợp có thể, bởi vì một trật tự của params vấn đề, ví dụ:
routes.MapRoute(
"CarSearch1",
"car/search/vendor/{vendor}/color/{color}/model/{model}",
new {controller = "car", action = "search"}
);
routes.MapRoute(
"CarSearch2",
"car/search/color/{color}/vendor/{vendor}/model/{model}",
new {controller = "car", action = "search"}
);
routes.MapRoute(
"CarSearch3",
"car/search/model/{model}/color/{color}/vendor/{vendor}",
new {controller = "car", action = "search"}
);
... tương tự. Đó là sự thật nếu bạn đang đi với MvcRouteHandler tiêu chuẩn.
Nhưng đó là một cách dễ dàng :)
Lựa chọn 3
Các khó khăn, nhưng, tôi nghĩ, cách thanh lịch nhất, là làm cho thực hiện IRouteHandler của riêng bạn - nó sẽ cho bạn nhiều hơn nữa linh hoạt trong thứ tự params. Nhưng một lần nữa, nó là một cách khó khăn, không đi với nó nếu bạn có một ứng dụng đơn giản. Vì vậy, chỉ cần cho ví dụ về làm thế nào để làm cho nó theo cách này (ví dụ rất đơn giản):
Thêm tuyến đường mới vào danh sách các tuyến đường:
routes.Add
(
new Route
(
"car/search/{*data}",
new RouteValueDictionary(new {controller = "car", action = "search", data = ""}),
new MyRouteHandler()
)
);
Thêm lớp mà sẽ tinh chỉnh các dây chuyền xử lý yêu cầu tiêu chuẩn:
class MyRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MyHttpHandler(requestContext);
}
}
class MyHttpHandler : MvcHandler
{
public MyHttpHandler(RequestContext requestContext) : base(requestContext)
{
}
protected override void ProcessRequest(HttpContextBase httpContext)
{
IController controller = new CarController();
(controller as Controller).ActionInvoker = new MyActionInvoker();
controller.Execute(RequestContext);
}
}
class MyActionInvoker : ControllerActionInvoker
{
protected override ActionResult InvokeActionMethod(MethodInfo methodInfo, IDictionary<string, object> parameters)
{
// if form of model/{model}/color/{color}/vendor/{vendor}
var data = ControllerContext.RouteData.GetRequiredString("data");
var tokens = data.Split('/');
var searchParams = new Dictionary<string, string>();
for (var i = 0; i < tokens.Length; i++)
{
searchParams.Add(tokens[i], tokens[++i]);
}
parameters["searchParams"] = searchParams;
return base.InvokeActionMethod(methodInfo, parameters);
}
}
Trong điều khiển:
public ActionResult Search(IDictionary<string, string> searchParams)
{
ViewData.Add
(
// output 'model = Corola, color = red, vendor = Toyota'
"SearchParams",
string.Join(", ", searchParams.Select(pair => pair.Key + " = " + pair.Value).ToArray())
);
return View();
}
Và nó sẽ làm việc với bất kỳ thông số tìm kiếm đặt hàng:
/car/search/vendor/Toyota/color/red/model/Corola
/car/search/color/red/model/Corola/vendor/Toyota
/car/search/model/Corola/color/red/vendor/Toyota
Nhưng cũng không quên làm một logic hệ liên kết, vì Html.ActionLink và Html.RenderLink sẽ không cung cấp cho bạn URL trong hình thức xinh đẹp của/xe/tìm kiếm/mô hình/Corola/color/red/vendor/Toyota, vì vậy bạn sẽ cần tạo một trình tạo liên kết tùy chỉnh.
Vì vậy, nếu bạn cần định tuyến thực sự linh hoạt - bạn nên làm theo cách này một cách khó khăn :)
Tôi nghĩ rằng hành động tốt nhất của tôi vào lúc này sẽ là Lựa chọn 1. Lựa chọn 2 là cách tôi bước đầu, nhưng có vẻ không hiệu quả khi phải đặt tất cả các kết hợp định tuyến có thể. Tùy chọn 3 có vẻ tốt cho sau này nếu tôi muốn refactor, nhưng là một MVC NOOB tôi sẽ dính với các tuyến đường dễ dàng. –
Câu trả lời tuyệt vời! @Eric đừng quên để upvote – AnthonyWJones
Cảm ơn bạn, Anthony :) – maxnk