【问题标题】:need help canonicalizing an HTTP GET form in asp.net mvc需要帮助在 asp.net mvc 中规范化 HTTP GET 表单
【发布时间】:2011-06-12 05:18:26
【问题描述】:

我在一个 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个action方法:

[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 个参数的第 4 条路由,等等。但是我似乎可以让它工作的唯一方法是将关键字保留为查询字符串参数。 (实际上,我可以通过在 CanonicalizeSearch 中的关键字前加上下划线并在 Search 中将其剥离来使其工作,但这很 hacky)。

有什么帮助吗?

【问题讨论】:

  • 找出为什么它没有传递参数——因为当我添加关键字时,我设置了这样的 url:“my-area/my-widgets/search/{size}-results- max/page-{page}/order-by-{sort}/keyword-{keyword}”。如果我将 url 设置为“my-area/my-widgets/search/{size}-results-max/page-{page}/order-by-{sort}/{keyword}”,它的路由就好了关键字 == null。

标签: asp.net-mvc asp.net-mvc-routing query-string http-get canonical-link


【解决方案1】:

您是否尝试在您的第一条路由中将UrlParameter.Optional 设置为keyword 参数?听起来很明显很愚蠢,但你从未排除过它。

【讨论】:

  • 谢谢...是的,当我写这篇文章时,我排除了很多事情,我试图保持简洁。我在这上面花了大约 10 个小时,这就是为什么我说“我想我已经尝试了一切......”在关键字上设置 UrlParameter.Optional 就是其中之一。我发现了原因——当我向路由 url 路径添加关键字时,我将其添加为“/keyword-{keyword}”。如果我把它写成 {keyword},一切都很好。我很快就会更新这个。
【解决方案2】:

我想通过尝试解决另一个问题,我偶然发现了一个更好的解决方案。

假设有人在关键字框中输入“我的搜索词”。提交导致 CanonicalizeSearch 方法路由到路径:

/my-area/my-widgets/search/10-results-per-page/page-1/
    order-by-Title-Ascending/my%20search%20terms

那些 %20 符号很烦人。我希望 URL 看起来像这样:

/my-area/my-widgets/search/10-results-per-page/page-1/
    order-by-Title-Ascending/my-search-terms

我可以通过以下方式完成此操作(注意从永久重定向到临时重定向的更改):

[ActionName("canonicalize-search")]
public virtual RedirectToRouteResult CanonicalizeSearch(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending")
{
    var result = RedirectToRoute(new
    {
        area = MVC.MyArea.Name,
        controller = MVC.MyArea.MyWidgets.Name,
        action = MVC.MyArea.MyWidgets.ActionNames.Search,
        page = page,
        size = size,
        sort = sort,
        keyword = (string.IsNullOrWhiteSpace(keyword)) 
            ? "no-keywords" : keyword.Replace(' ', '-'),
    });
    TempData["keyword"] = keyword;
    return result;
}

[ActionName("search")]
public virtual ViewResult Search(string keyword, 
    int page = 1, int size = 10, string sort = "Title-Ascending")
{
    keyword = TempData["keyword"] as string ?? keyword;
    // code to perform query
    return View(model);
}

这解决了我在这里发布的问题和 %20 符号的删除。每当关键字为空或空白时,它都会呈现 URL

/my-area/my-widgets/search/10-results-per-page/page-1/
    order-by-Title-Ascending/no-keywords

...并且路由将始终匹配。

【讨论】:

    猜你喜欢
    • 2011-11-15
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2010-09-13
    相关资源
    最近更新 更多