【问题标题】:How do you persist querystring values in asp.net mvc?你如何在 asp.net mvc 中持久化查询字符串值?
【发布时间】:2009-05-20 19:19:23
【问题描述】:

在 asp.net mvc 中持久化查询字符串值的好方法是什么?

如果我有一个网址: /questions?page=2&sort=newest&items=50&showcmets=1&search=abcd

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

我可以想到两种方法来做到这一点:

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

一个比另一个更好吗?这些是唯一的选择还是有更好的方法来做到这一点?

【问题讨论】:

    标签: asp.net-mvc query-string viewdata


    【解决方案1】:

    我为此使用了扩展方法:

    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 约定可以做到这一点而无需编写代码行。
    【解决方案2】:

    我将在视图中处理 QueryString(您的选项 #1),而不是从控制器传递它。这种方法使视图更加独立,允许您将其转换为视图控件并在不同的视图中重复使用。

    注意:直接在视图中访问 QueryString 似乎违反了分离模型和视图的设计原则,但实际上这些数据是与视图相关的导航问题,而不是模型的一部分.

    【讨论】:

    • 感谢您的输入和推理。你的笔记正是我想通过 ViewData 传递它的原因。
    【解决方案3】:

    我只会保留 Session 中的值,只需要分页链接;

    /questions?page=2

    /questions?page=3

    我不使用 QueryString 的一个原因是我不希望用户看到我传递给程序的值。这让他们很容易进入地址栏并开始更改值以“看看会发生什么”。有了这段代码,他们所能做的就是改变页码。

    【讨论】:

    • 这是我想了一秒钟但想将其保留在查询字符串中的内容。
    • 您希望将 &sort=newest&items=50&showcmets=1&search=abcd 留在查询字符串中的一个很好的理由是,人们可以为搜索添加书签。您是否有任何理由不希望人们直接编辑查询字符串中的 &search= 值并“看看会发生什么”?
    【解决方案4】:

    这是我在 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 的内容传递其余的路由值。

    【讨论】:

      猜你喜欢
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多