Чистый способ генерации параметров QueryString для веб-запросов - PullRequest
3 голосов
/ 17 декабря 2008

Я столкнулся с проблемой в моем текущем приложении, которая требовала возиться со строкой запроса в базовом классе Page (от которого наследуются все мои страницы), чтобы решить эту проблему. Поскольку некоторые из моих страниц используют строку запроса, мне было интересно, существует ли какой-либо класс, обеспечивающий чистую и простую манипуляцию строкой запроса.

Пример кода:

// What happens if I want to future manipulate the query string elsewhere
// (e.g. maybe rewrite when the request comes back in)
// Or maybe the URL already has a query string (and the ? is invalid)

Response.Redirect(Request.Path + "?ProductID=" + productId);

Ответы [ 6 ]

4 голосов
/ 17 декабря 2008

Я надеялся найти решение, встроенное в фреймворк, но не смог. (те методы, которые находятся в фреймворке, требуют много работы, чтобы сделать его простым и чистым)

После попытки нескольких альтернатив я в настоящее время использую следующий метод расширения: (опубликуйте лучшее решение или комментарий, если у вас есть)

public static class UriExtensions
{
    public static Uri AddQuery(this Uri uri, string name, string value)
    {
        string newUrl = uri.OriginalString;

        if (newUrl.EndsWith("&") || newUrl.EndsWith("?"))
            newUrl = string.Format("{0}{1}={2}", newUrl, name, value);
        else if (newUrl.Contains("?"))
            newUrl = string.Format("{0}&{1}={2}", newUrl, name, value);
        else
            newUrl = string.Format("{0}?{1}={2}", newUrl, name, value);

        return new Uri(newUrl);
    }
}

Этот метод расширения обеспечивает очень чистое перенаправление и манипуляции с URI:

Response.Redirect(Request.Url.AddQuery("ProductID", productId).ToString());

// Will generate a URL of www.google.com/search?q=asp.net
var url = new Uri("www.google.com/search").AddQuery("q", "asp.net")

и будет работать для следующих URL:

"http://www.google.com/somepage"
"http://www.google.com/somepage?"
"http://www.google.com/somepage?OldQuery=Data"
"http://www.google.com/somepage?OldQuery=Data&"
4 голосов
/ 17 декабря 2008

Используйте HttpUtility.ParseQueryString, как кто-то предложил (а затем удалил).

Это будет работать, потому что возвращаемое значение из этого метода на самом деле HttpValueCollection, которое наследует NameValueCollection (и является внутренним, вы не можете ссылаться на него напрямую). Затем вы можете установить имена / значения в коллекции в обычном режиме (включая добавление / удаление) и вызвать ToString, что приведет к созданию законченной строки запроса, поскольку HttpValueCollection переопределяет ToString для воспроизведения действительной строки запроса.

2 голосов
/ 17 декабря 2008

Обратите внимание, что какой бы маршрут вы ни использовали, вы должны действительно кодировать значения - Uri.EscapeDataString должен сделать это за вас:

string s = string.Format("http://somesite?foo={0}&bar={1}",
            Uri.EscapeDataString("&hehe"),
            Uri.EscapeDataString("#mwaha"));
0 голосов
/ 03 марта 2011

Я нашел способ легко манипулировать с получением параметров.

public static string UrlFormatParams(this string url, string paramsPattern, params object[] paramsValues)
{
    string[] s = url.Split(new string[] {"?"}, StringSplitOptions.RemoveEmptyEntries);
    string newQueryString = String.Format(paramsPattern, paramsValues);
    List<string> pairs = new List<string>();

    NameValueCollection urlQueryCol = null;
    NameValueCollection newQueryCol = HttpUtility.ParseQueryString(newQueryString);

    if (1 == s.Length)
    {
        urlQueryCol = new NameValueCollection();
    }
    else
    {
        urlQueryCol = HttpUtility.ParseQueryString(s[1]);
    }



    for (int i = 0; i < newQueryCol.Count; i++)
    {
        string key = newQueryCol.AllKeys[i];
        urlQueryCol[key] = newQueryCol[key];
    }

    for (int i = 0; i < urlQueryCol.Count; i++)
    {
        string key = urlQueryCol.AllKeys[i];
        string pair = String.Format("{0}={1}", key, urlQueryCol[key]);
        pairs.Add(pair);
    }

    newQueryString = String.Join("&", pairs.ToArray());

    return String.Format("{0}?{1}", s[0], newQueryString);
}

Используйте это как

"~/SearchInHistory.aspx".UrlFormatParams("t={0}&s={1}", searchType, searchString)
0 голосов
/ 18 декабря 2008

Проверить это !!!

// First Get The Method Used by Request i.e Get/POST from current Context
string method = context.Request.HttpMethod;

// Declare a NameValueCollection Pair to store QueryString parameters from Web Request
NameValueCollection queryStringNameValCollection = new NameValueCollection();

if (method.ToLower().Equals("post")) // Web Request Method is Post
{
   string contenttype = context.Request.ContentType;

   if (contenttype.ToLower().Equals("application/x-www-form-urlencoded"))
   {
      int data = context.Request.ContentLength;
      byte[] bytData = context.Request.BinaryRead(context.Request.ContentLength);
      queryStringNameValCollection = context.Request.Params;
   }
}
else // Web Request Method is Get
{
   queryStringNameValCollection = context.Request.QueryString;
}

// Now Finally if you want all the KEYS from QueryString in ArrayList
ArrayList arrListKeys = new ArrayList();

for (int index = 0; index < queryStringNameValCollection.Count; index++)
{
   string key = queryStringNameValCollection.GetKey(index);
   if (!string.IsNullOrEmpty(key))
   {
      arrListKeys.Add(key.ToLower());
   }
}
0 голосов
/ 18 декабря 2008

Обычно я просто перестраиваю строку запроса. Запрос имеет коллекцию QueryString.

Вы можете выполнить итерацию для этого, чтобы получить текущие (не кодированные) параметры, и просто объединить их (кодируя по мере необходимости) с соответствующими разделителями.

Преимущество заключается в том, что Asp.Net сделал для вас оригинальный анализ, поэтому вам не нужно беспокоиться о крайних случаях, таких как трейлинг & and? S.

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