На моей базовой странице мне нужно удалить элемент из строки запроса и перенаправить. Я не могу использовать
Request.QueryString.Remove("foo")
потому что коллекция доступна только для чтения. Есть ли способ получить строку запроса (кроме этого одного элемента) без итерации по коллекции и ее повторного построения?





Response.Redirect(String.Format("nextpage.aspx?{0}", Request.QueryString.ToString().Replace("foo", "mangledfoo")));
Я быстро взламываю, мало тебя спасает. Но foo не будет присутствовать для кода, ожидающего его в nextpge.aspx :)
Я поставил +1, я не знаю, кто изменил мод, я подумал, что это разумный взлом ?! : S
Можете ли вы клонировать коллекцию, а затем перенаправить на страницу с клонированной (и измененной) коллекцией?
Я знаю, что это не намного лучше, чем повторение ...
Вам нужно будет восстановить URL-адрес, а затем перенаправить. Что-то вроде этого:
string url = Request.RawUrl;
NameValueCollection params = Request.QueryString;
for (int i=0; i<params.Count; i++)
{
if (params[i].GetKey(i).ToLower() == "foo")
{
url += string.Concat((i==0 ? "?" : "&"), params[i].GetKey(i), " = ", params.Get(i));
}
}
Response.Redirect(url);
В любом случае, я не тестировал это или что-то в этом роде, но это должно сработать (или, по крайней мере, направить вас в правильном направлении)
"без итерации по коллекции"?
Да, мой ответ действительно такой: «Вы не можете, вам придется его перестроить», поскольку без него невозможно сделать то, что он просит. Вы можете избежать итерации и скопировать в новый массив и удалить элемент, но вам все равно придется перебирать его, чтобы создать URL-адрес для перенаправления.
Интересный вопрос. Я не вижу реальной альтернативы ручному копированию коллекции, поскольку Скопировать в позволит вам получить только значения (а не ключи).
Я думаю, что HollyStyles 'Взлом будет работать (хотя я бы нервничал, вставив Replace в QueryString - очевидно, в зависимости от варианта использования), но есть одна вещь, которая меня беспокоит ...
Если целевая страница не читает его, зачем вам удалять его из QueryString?
Его просто проигнорируют?
В противном случае, я думаю, вам просто нужно укусить пулю и создать метод util, который изменит коллекцию за вас.
Аааааааааааааааааааааааа! Теперь я понимаю, что да, у меня были аналогичные проблемы с SiteMap, выполняющим полное сравнение строки.
Поскольку об изменении другого исходного кода (то есть о поиске) не может быть и речи, я бы, вероятно, сказал, что лучше всего выполнить замену строки. Хотя, честно говоря, если вы часто сталкиваетесь с кодом, подобным этому, было бы столь же быстро настроить служебную функцию для клонирования коллекции, взяв из нее массив значений для фильтрации.
Таким образом, вам больше не придется беспокоиться о таких проблемах :)
Я еще никого не понижал в этой теме. Но даунмод помечен как «это не помогло», и пока очень мало ответов было полезным, поэтому я могу понять, почему некоторые люди могут их занижать.
Спасибо за исправление, я думаю, у кого-то игры или плохой день, мы все еще находимся в бета-версии :) Так что разделяю любовь, +1 назад.
@Espo, я действительно имел в виду пост Холли, это показалось разумным взломом .. Похоже, кто-то только что вошел и всех обидел ..
<b>> Если целевая страница не читает его,> зачем вам удалять его из> QueryString? </b> Отличный вопрос. Я использую элемент управления меню «черный ящик», который определяет, где вы находитесь в дереве, глядя на строку запроса. Однако он выполняет точное сравнение строк, поэтому он запутывается, когда в строке запроса есть лишние данные. На странице поиска к строке запроса добавляется "& terms =" для выделения, так что это мешает. Да, перестройка строки запроса и перенаправление, безусловно, неоптимально. Однако один взлом дешевле (мы магазин времени и материалов) для клиента, чем повторный
The search page appends "&terms = " to the query string for highlighting, so it messes it up.
Другой вариант - замена регулярного выражения. Если вы знаю точно, что & terms находится в середине коллекции, где-то оставьте конечный & в регулярном выражении, если вы знаю точно, он находится в конце, отбросьте конечный & и измените заменяющую строку "&" на String.Empty
Response.Redirect(String.Format("nextpage.aspx?{0}", Regex.Replace(Request.QueryString.ToString(), "&terms=.*&", "&"));
Вы можете избежать прикосновения к исходной строке запроса, вместо этого работая с ее копией. Затем вы можете перенаправить страницу на URL-адрес, содержащий измененную строку запроса, например:
var nvc = new NameValueCollection();
nvc.Add(HttpUtility.ParseQueryString(Request.Url.Query));
nvc.Remove("foo");
string url = Request.Url.AbsolutePath;
for (int i = 0; i < nvc.Count; i++)
url += string.Format("{0}{1} = {2}", (i == 0 ? "?" : "&"), nvc.Keys[i], nvc[i]);
Response.Redirect(url);
Обновлять:
Оказывается, мы можем упростить код так:
var nvc = HttpUtility.ParseQueryString(Request.Url.Query);
nvc.Remove("foo");
string url = Request.Url.AbsolutePath + "?" + nvc.ToString();
Response.Redirect(url);
Возврат HttpUtility.ParseQueryString(Request.Url.Query) - QueryStringValueCollection. Унаследован от NameValueCollection.
var qs = HttpUtility.ParseQueryString(Request.Url.Query);
qs.Remove("foo");
string url = "~/Default.aspx";
if (qs.Count > 0)
url = url + "?" + qs.ToString();
Response.Redirect(url);
Request.Url.GetLeftPart(UriPartial.Path) должен делать это
Также удобно добавить URL-адрес в документацию: msdn.microsoft.com/en-us/library/system.uri.getleftpart.aspx
Я обнаружил, что это более элегантное решение
var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString());
qs.Remove("item");
Console.WriteLine(qs.ToString());
Вот решение, которое использует LINQ против Request.QueryString, что позволяет при необходимости выполнять сложную фильтрацию параметров qs.
В приведенном ниже примере показано, как я отфильтровываю параметр uid для создания относительного URL-адреса, готового для перенаправления.
Раньше: http://www.domain.com/home.aspx?color=red&uid=1&name=bob
После: ~/home.aspx?color=red&name=bob
Удалить параметр QS из url
var rq = this.Request.QueryString;
var qs = string.Join("&", rq.Cast<string>().Where(k => k != "uid").Select(k => string.Format("{0} = {1}", k, rq[k])).ToArray());
var url = string.Concat("~", Request.RawUrl.Split('?')[0], "?", qs);
Причина, по которой строка запроса доступна только для чтения, заключается в том, что строка запроса предоставляется браузером. Вы не можете сделать это, не перебирая коллекцию или не создавая ее заново, если вы знаете все пары ключ / значение, которые вам нужны.