我在一个 asp.net mvc 站点中有一个表单,它有 3 个用途:分页、排序和搜索。这些项目都应该以相同的形式呈现,因为返回正确的搜索结果取决于所有 3 个方面的变量。我想要做的是将参数移出查询字符串并将它们放在规范的 URL 中。
我快到了,这是我到目前为止的 3 个路由配置(使用 T4MVC 作为区域、控制器和操作名称):
context.MapRoute(null,
"my-area/my-widgets/search/{size}-results-max/page-{page}/order-by-{sort}",
new
{
area = MVC.MyArea.Name,
controller = MVC.MyArea.MyWidgets.Name,
action = MVC.MyArea.MyWidgets.ActionNames.Search,
page = UrlParameter.Optional,
size = UrlParameter.Optional,
sort = UrlParameter.Optional,
}
);
context.MapRoute(null,
"my-area/my-widgets/canonicalize-search",
new
{
area = MVC.MyArea.Name,
controller = MVC.MyArea.MyWidgets.Name,
action = MVC.MyArea.MyWidgets.ActionNames.CanonicalizeSearch,
}
);
context.MapRoute(null,
"my-area/my-widgets",
new
{
area = MVC.MyArea.Name,
controller = MVC.MyArea.MyWidgets.Name,
action = MVC.MyArea.MyWidgets.ActionNames.CanonicalizeSearch,
}
);
视图中的表单使用以下语法提交到 CanonicalizeSearch 路由:
@using (Html.BeginForm(MVC.MyArea.MyWidgets.CanonicalizeSearch(),
FormMethod.Get))
在 MyWidgetsController 中,有 2 个操作方法:
[ActionName("canonicalize-search")]
public virtual RedirectToRouteResult CanonicalizeSearch(string keyword,
int page = 1, int size = 10, string sort = "Title-Ascending")
{
var result = RedirectToRoutePermanent(new
{
area = MVC.MyArea.Name,
controller = MVC.MyArea.MyWidgets.Name,
action = MVC.MyArea.MyWidgets.ActionNames.Search,
page = page,
size = size,
sort = sort,
keyword = keyword,
});
return result;
}
[ActionName("search")]
public virtual ViewResult Search(string keyword,
int page = 1, int size = 10, string sort = "Title-Ascending")
{
// code to perform query
return View(model);
}
这适用于将所有查询字符串变量移动到规范化路由中,除了关键字。如果我将关键字参数添加到第一个路由,CanonicalizeSearch 操作仅在关键字不为空、空或空格时重定向到搜索操作。这不好,因为当没有输入关键字时,它会导致无法浏览页面结果。
我想我已经尝试了一切——在控制器中给关键字一个默认值,添加第四条路由,将关键字添加到其他 3 个参数等。但是我似乎可以让它工作的唯一方法是保持关键字为一个查询字符串参数。(实际上,我可以通过在 CanonicalizeSearch 中的关键字前加上下划线并在 Search 中将其剥离来使其工作,但这很 hacky)。
有什么帮助吗?