Изменить значение строки запроса одного URL - PullRequest
24 голосов
/ 28 сентября 2010

У меня есть страница ASP.NET, которая принимает ряд параметров в строке запроса:

search.aspx?q=123&source=WebSearch

Это будет отображать первую страницу результатов поиска. Теперь при рендеринге этой страницы я хочу отобразить набор ссылок, которые позволяют пользователю переходить на разные страницы в результатах поиска. Я могу сделать это просто добавив &page=1 или &page=2 и т. Д.

Ситуация усложняется тем, что я хочу сохранить строку входного запроса с исходной страницы для каждого параметра, кроме того, который я пытаюсь изменить. В URL могут быть другие параметры, используемые другими компонентами, и значение, которое я пытаюсь заменить, может быть определено или не определено:

search.aspx?q=123&source=WebSearch&page=1&Theme=Blue

В этом случае, чтобы создать ссылку на следующую страницу результатов, я хочу изменить page=1 на page=2, оставив остальную часть строки запроса без изменений.

Есть ли встроенный способ сделать это, или мне нужно выполнить весь анализ / рекомбинацию строк вручную?

Ответы [ 5 ]

53 голосов
/ 28 сентября 2010

Вы не можете изменить QueryString напрямую, так как он доступен только для чтения. Вам нужно будет получить значения, изменить их, а затем собрать их обратно. Попробуйте это:

var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
nameValues.Set("page", "2");
string url = Request.Url.AbsolutePath;
string updatedQueryString = "?" + nameValues.ToString();
Response.Redirect(url + updatedQueryString);

Метод ParseQueryString возвращает NameValueCollection (на самом деле он действительно возвращает HttpValueCollection, который кодирует результаты, , как я упоминал в ответе другому вопрос ). Затем вы можете использовать метод Set для обновления значения. Вы также можете использовать метод Add для добавления нового или Remove для удаления значения. Наконец, вызов ToString() для имени NameValueCollection возвращает пары имя-значение в name1=value1&name2=value2 формате строки запроса. После этого добавьте его к URL-адресу и перенаправьте.

Кроме того, вы можете добавить новый ключ или изменить существующий, используя индексатор:

nameValues["temp"] = "hello!"; // add "temp" if it didn't exist
nameValues["temp"] = "hello, world!"; // overwrite "temp"
nameValues.Remove("temp"); // can't remove via indexer

Вам может потребоваться добавить using System.Collections.Specialized;, чтобы использовать NameValueCollection класс.

12 голосов
/ 28 сентября 2010

Вы можете сделать это без лишних затрат на перенаправление (что немаловажно). Лично я предпочитаю работать с NameValueCollection, которым на самом деле является строка запроса, но с использованием отражения:

// reflect to readonly property 
PropertyInfo isReadOnly = typeof(System.Collections.Specialized.NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic); 

// make collection editable 
isReadOnly.SetValue(this.Request.QueryString, false, null); 

// remove 
this.Request.QueryString.Remove("foo"); 

// modify 
this.Request.QueryString.Set("bar", "123"); 

// make collection readonly again 
isReadOnly.SetValue(this.Request.QueryString, true, null); 
5 голосов
/ 28 сентября 2010

Используя этот вспомогательный класс QueryStringBuilder , вы можете получить текущий QueryString и вызвать метод Add, чтобы изменить существующую пару ключ / значение ...

//before: "?id=123&page=1&sessionId=ABC"
string newQueryString = QueryString.Current.Add("page", "2");
//after: "?id=123&page=2&sessionId=ABC"
0 голосов
/ 07 сентября 2017

Это довольно произвольно, по крайней мере, в .NET Core.И все это сводится к asp-all-route-data

Рассмотрим следующий тривиальный пример (взят из модели представления «paginator», которую я использую практически в каждом проекте):

public class SomeViewModel 
{

    public Dictionary<string, string> NextPageLink(IQueryCollection query)
    {
        /*
         * NOTE: how you derive the "2" is fully up to you
         */
        return ParseQueryCollection(query, "page", "2");
    }

    Dictionary<string, string> ParseQueryCollection(IQueryCollection query, string replacementKey, string replacementValue)
    {
        var dict = new Dictionary<string, string>()
        {
            { replacementKey, replacementValue }
        };

        foreach (var q in query)
        {
            if (!string.Equals(q.Key, replacementKey, StringComparison.OrdinalIgnoreCase))
            {
                dict.Add(q.Key, q.Value);
            }
        }

        return dict;
    }
}

Затем, чтобы использовать в своем представлении, просто передайте метод текущей коллекции запросов из Context.Request:

<a asp-all-route-data="@Model.NextPageLink(Context.Request.Query)">Next</a>
0 голосов
/ 28 сентября 2010

Использование URIBuilder. В частности, текст ссылки Свойство запроса

Я считаю, что делает то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...