Проанализируйте и измените строку запроса in.NET основной


мне дается абсолютный URI, который содержит строку запроса. Я хочу безопасно добавить значение в строку запроса и изменить существующий параметр.

Я бы предпочел не лавировать &foo=bar, или использовать регулярные выражения, URI экранирование сложно. Скорее я хочу использовать встроенный механизм, который, как я знаю, будет делать это правильно и обрабатывать побег.

Я нашелaТ ответов, которые все используют HttpUtility. Однако это существо ASP.NET ядро, больше нет системы.Веб-сборка больше, таким образом, не более HttpUtility.

каков подходящий способ сделать это в ASP.NET ядро при ориентации на основную среду выполнения?

5 67

5 ответов:

я понял, вы можете сделать это с помощью Microsoft.AspNetCore.WebUtilities.QueryHelpers на Microsoft.AspNetCore.WebUtilities.

чтобы разобрать его в словарь:

var uri = new Uri(context.RedirectUri);
var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);

обратите внимание, что в отличие от ParseQueryString в систему.Web, это возвращает словарь типа IDictionary<string, string[]>, поэтому значение представляет собой массив строк. Так словарь обрабатывает несколько параметров строки запроса с одинаковым именем.

если вы хотите добавить параметр в строку запроса, вы можете использовать другой метод QueryHelpers:

var parametersToAdd = new System.Collections.Generic.Dictionary<string, string> { { "resource", "foo" } };
var someUrl = "http://www.google.com";
var newUri = Microsoft.AspNetCore.WebUtilities.QueryHelpers.AddQueryString(someUrl, parametersToAdd);

самый простой и интуитивно понятный способ взять абсолютный URI и управлять его строкой запроса с помощью ASP.NET основные пакеты только, может быть сделано в несколько простых шагов:

Установка Пакетов

PM> Install-Package Microsoft.AspNetCore.WebUtilities
PM> Install-Package Microsoft.AspNetCore.Http.Расширения

Важные Классы

просто чтобы указать на них, вот два важных класса, которые мы будем использовать: QueryHelpers, StringValues,QueryBuilder.

Код

// Raw URI including query string with multiple parameters
var rawurl = "https://bencull.com/some/path?key1=val1&key2=val2&key2=valdouble&key3=";

// Parse URI, and grab everything except the query string.
var uri = new Uri(rawurl);
var baseUri = uri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.UriEscaped);

// Grab just the query string part
var query = QueryHelpers.ParseQuery(uri.Query);

// Convert the StringValues into a list of KeyValue Pairs to make it easier to manipulate
var items = query.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();

// At this point you can remove items if you want
items.RemoveAll(x => x.Key == "key3"); // Remove all values for key
items.RemoveAll(x => x.Key == "key2" && x.Value == "val2"); // Remove specific value for key

// Use the QueryBuilder to add in new items in a safe way (handles multiples and empty values)
var qb = new QueryBuilder(items);
qb.Add("nonce", "testingnonce");
qb.Add("payerId", "pyr_");

// Reconstruct the original URL with new query string
var fullUri = baseUri + qb.ToQueryString();

чтобы быть в курсе любых изменений, вы можете проверить мой блог об этом здесь:http://benjii.me/2017/04/parse-modify-query-strings-asp-net-core/

HttpRequest есть Query свойство, которое предоставляет разобранную строку запроса через IReadableStringCollection интерфейс:

/// <summary>
/// Gets the query value collection parsed from owin.RequestQueryString.
/// </summary>
/// <returns>The query value collection parsed from owin.RequestQueryString.</returns>
public abstract IReadableStringCollection Query { get; }

эта дискуссия на GitHub указывает на это также.

эта функция возвращает Dictionary<string, string> и не использовать Microsoft.xxx совместимость

принимает кодировку параметров в обе стороны

принимает дубликаты ключей (возвращает последнее значение)

var rawurl = "https://emp.com/some/path?key1.name=a%20line%20with%3D&key2=val2&key2=valdouble&key3=&key%204=44#book1";
var uri = new Uri(rawurl);
Dictionary<string, string> queryString = ParseQueryString(uri.Query);

// queryString return:
// key1.name, a line with=
// key2, valdouble
// key3, 
// key 4, 44

public Dictionary<string, string> ParseQueryString(string requestQueryString)
{
    Dictionary<string, string> rc = new Dictionary<string, string>();
    string[] ar1 = requestQueryString.Split(new char[] { '&', '?' });
    foreach (string row in ar1)
    {
        if (string.IsNullOrEmpty(row)) continue;
        int index = row.IndexOf('=');
        if (index < 0) continue;
        rc[Uri.UnescapeDataString(row.Substring(0, index))] = Uri.UnescapeDataString(row.Substring(index + 1)); // use Unescape only parts          
     }
     return rc;
}

важно отметить, что в то время, как верхний ответ был помечен как правильный, что Microsoft.AspNetCore.WebUtilities было крупное обновление версии (от 1.x. x до 2.х.х).

что сказал, Если вы строите в отношении netcoreapp1.1 вам нужно будет запустить следующее, которое устанавливает последнюю поддерживаемую версию 1.1.2:

Install-Package Microsoft.AspNetCore.WebUtilities -Version 1.1.2