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

时间:2022-04-09 04:10:19

What is a good way to persist querystring values in asp.net mvc?

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

If I have a url: /questions?page=2&sort=newest&items=50&showcomments=1&search=abcd

如果我有一个url: /问题?页=2&排序=newest&items=50&showcomments=1&search=abcd

On paging links I want to keep those querystring values in all the links so they persist when the user clicks on the "next page" for example (in this case the page value would change, but the rest would stay the same)

在分页链接中,我希望将这些querystring值保存在所有链接中,这样当用户单击“下一页”时,这些值将保持不变(在本例中,页面值将会改变,但其余的值将保持不变)

I can think of 2 ways to do this:

我可以想到两种方法:

  1. Request.Querystring in the View and add the values to the links
  2. 请求。在视图中查询字符串并将值添加到链接中
  3. Pass each querystring value from the Controller back into the View using ViewData
  4. 使用ViewData将每个querystring值从控制器传回视图

Is one better than the other? Are those the only options or is there a better way to do this?

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

4 个解决方案

#1


6  

I would process the QueryString in the view (your option #1), instead of passing it in from the controller. This approach makes the view more self-contained, allowing you to convert it into a view control and re-use it across different views.

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

Note: Accessing the QueryString directly in the view may seem like a violation of the design principle of separating the Model and View, but in reality this data is a navigational concern which is related to the view, not really part of the model.

注意:在视图中直接访问QueryString看起来似乎违背了分离模型和视图的设计原则,但实际上,该数据是与视图相关的导航关注,而不是模型的一部分。

#2


8  

i use a extension method for that:

我使用了扩展方法:

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);
    }

#3


1  

I would just keep the values in the Session that way the paging links only need to have;

我将在会话中保留值,这样分页链接只需要拥有;

/questions?page=2

/问题吗? = 2页

/questions?page=3

/问题吗? = 3页

The one reason why I would not us the QueryString is because I don't want the user to see the values that I am passing to the program. It makes it way too easy for them to go into the address bar and start changing the values to 'see what happens'. With this code all they could do is change the page number.

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

#4


0  

Here's how I done it in Asp.Net Core, first assign the query string parameters to ViewBags in your controller:

这是我在Asp中做的。Net Core,首先将查询字符串参数分配给控制器中的viewbag:

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

    ...
}

Then pass the values to your links like so:

然后将值传递给您的链接,如下所示:

<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>

Note that every link keep its own actual value and pass the rest of the route values through what we passed to ViewBag.

注意,每个链接都保留自己的实际值,并将剩下的路由值传递给ViewBag。

#1


6  

I would process the QueryString in the view (your option #1), instead of passing it in from the controller. This approach makes the view more self-contained, allowing you to convert it into a view control and re-use it across different views.

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

Note: Accessing the QueryString directly in the view may seem like a violation of the design principle of separating the Model and View, but in reality this data is a navigational concern which is related to the view, not really part of the model.

注意:在视图中直接访问QueryString看起来似乎违背了分离模型和视图的设计原则,但实际上,该数据是与视图相关的导航关注,而不是模型的一部分。

#2


8  

i use a extension method for that:

我使用了扩展方法:

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);
    }

#3


1  

I would just keep the values in the Session that way the paging links only need to have;

我将在会话中保留值,这样分页链接只需要拥有;

/questions?page=2

/问题吗? = 2页

/questions?page=3

/问题吗? = 3页

The one reason why I would not us the QueryString is because I don't want the user to see the values that I am passing to the program. It makes it way too easy for them to go into the address bar and start changing the values to 'see what happens'. With this code all they could do is change the page number.

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

#4


0  

Here's how I done it in Asp.Net Core, first assign the query string parameters to ViewBags in your controller:

这是我在Asp中做的。Net Core,首先将查询字符串参数分配给控制器中的viewbag:

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

    ...
}

Then pass the values to your links like so:

然后将值传递给您的链接,如下所示:

<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>

Note that every link keep its own actual value and pass the rest of the route values through what we passed to ViewBag.

注意,每个链接都保留自己的实际值,并将剩下的路由值传递给ViewBag。