如何在ASP.NET MVC中保留查询字符串的值?

14

如何在asp.net mvc中持久化查询字符串的值?

如果我有一个url:

/questions?page=2&sort=newest&items=50&showcomments=1&search=abcd

在分页链接中,我希望保留所有查询字符串的值,以便用户单击“下一页”时它们仍然存在(在这种情况下,页面值会更改,但其余值将保持不变)

我可以想到两种方法来实现:

  1. 在视图中使用Request.Querystring并将其添加到链接中
  2. 通过ViewData从控制器将每个查询字符串值传回视图

哪一种更好?还是说这些是唯一的选择?还是有更好的方法来实现这个功能?

4个回答

8
我使用扩展方法来实现这个功能:
public static string RouteLinkWithExtraValues(
        this HtmlHelper htmlHelper,
        string name,
        object values)
    {
        var routeValues = new RouteValueDictionary(htmlHelper.ViewContext.RouteData.Values);

        var extraValues = new RouteValueDictionary(values);
        foreach (var val in extraValues)
        {
            if (!routeValues.ContainsKey(val.Key))
                routeValues.Add(val.Key, val.Value);
            else
                routeValues[val.Key] = val.Value;
        }

        foreach (string key in htmlHelper.ViewContext.HttpContext.Request.Form)
        {
            routeValues[key] = htmlHelper.ViewContext.HttpContext.Request.Form[key];
        }

        foreach (string key in htmlHelper.ViewContext.HttpContext.Request.QueryString)
        {
            if (!routeValues.ContainsKey(key) && htmlHelper.ViewContext.HttpContext.Request.QueryString[key] != "")
                routeValues[key] = htmlHelper.ViewContext.HttpContext.Request.QueryString[key];
        }

        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);

        return string.Format("<a href=\"{0}\">{1}</a>", urlHelper.RouteUrl(routeValues), name);
    }

我从未想过这个。看起来很有趣,但对我来说可能太复杂了。我希望有一些MVC约定可以在不编写代码的情况下完成这个。 - dtc

7
我会在视图中处理 QueryString(您的选项#1),而不是从控制器传递它。这种方法使视图更加自包含,可以将其转换为视图控件并在不同的视图之间重复使用。
注意:直接在视图中访问 QueryString 可能看起来像违反了模型和视图分离的设计原则,但实际上这些数据是与视图相关的导航问题,而不是模型的一部分。

感谢您的输入和推理。您的笔记正是我考虑通过ViewData传递它的原因。 - dtc

1

我会将值保留在Session中,这样分页链接只需要有以下内容:

/questions?page=2

/questions?page=3

我不使用QueryString的原因是我不希望用户看到我传递给程序的值。这样他们很容易进入地址栏并开始更改值以“看看会发生什么”。使用此代码,他们只能更改页面编号。


这是我一开始想到的,但我希望将其保留在查询字符串中。 - dtc
你想在查询字符串中留下&sort=newest&items=50&showcomments=1&search=abcd的一个好理由是,这样人们可以将搜索结果加入书签。有没有任何理由不希望人们直接编辑查询字符串中的&search=值并“看看会发生什么”? - Michael Bylstra

0

以下是我在Asp.Net Core中完成它的方式,首先在您的控制器中将查询字符串参数分配给ViewBags:

[HttpGet("/[controller]/[action]/{categoryId?}/{contractTypeId?}/{locationId?}")]
public IActionResult Index(Guid categoryId, int contractTypeId, Guid locationId)
{
    ViewBag.CategoryId = categoryId;
    ViewBag.ContractTypeId = contractTypeId;
    ViewBag.LocationId = locationId;

    ...
}

然后将这些值传递到您的链接中,如下所示:

<a asp-action="Index" asp-controller="Jobs"
   asp-route-categoryId="@teachingCategory.Id"
   asp-route-contractTypeId="@ViewBag.ContractTypeId"
   asp-route-locationId="@ViewBag.LocationId">
   @teachingCategory.Description (@teachingCategory.Rank)
</a>

<a asp-action="Index" asp-controller="Jobs"
   asp-route-categoryId="@ViewBag.CategoryId"
   asp-route-contractTypeId="@typeOfEmployment.Id"
   asp-route-locationId="@ViewBag.LocationId">
   @typeOfEmployment.Name
</a>

<a asp-action="Index" asp-controller="Jobs"
   asp-route-categoryId="@ViewBag.CategoryId"
   asp-route-contractTypeId="@ViewBag.ContractTypeId"
   asp-route-locationId="@item.Id">
   @item.Id
</a>

请注意,每个链接都保留其自身的实际值,并通过我们传递给 ViewBag 的方式传递其余路由值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接