IT story

.NET Core에서 쿼리 문자열 구문 분석 및 수정

hot-time 2020. 8. 26. 19:23
반응형

.NET Core에서 쿼리 문자열 구문 분석 및 수정


쿼리 문자열이 포함 된 절대 URI가 제공됩니다. 쿼리 문자열에 값을 안전하게 추가하고 기존 매개 변수를 변경하려고합니다.

나는 택 &foo=bar하거나 정규 표현식을 사용 하지 않는 것을 선호합니다 . URI 이스케이프는 까다 롭습니다. 오히려이 작업을 올바르게 수행하고 이스케이프를 처리 할 수있는 기본 제공 메커니즘을 사용하고 싶습니다.

나는 한 발견 모두 사용이 답변을 . 그러나 이것은 ASP.NET Core이므로 더 이상 System.Web 어셈블리가 없으므로 더 이상 . HttpUtilityHttpUtility

코어 런타임을 대상으로하는 동안 ASP.NET Core에서이 작업을 수행하는 적절한 방법은 무엇입니까?


ASP.NET Core 1 또는 2를 사용 Microsoft.AspNetCore.WebUtilities.QueryHelpers하는 경우 Microsoft.AspNetCore.WebUtilities 패키지 에서이 작업을 수행 할 수 있습니다 .

ASP.NET Core 3.0 이상을 사용 WebUtilities하는 경우은 이제 ASP.NET SDK의 일부이며 별도의 nuget 패키지 참조가 필요하지 않습니다.

사전으로 구문 분석하려면 :

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

ParseQueryStringSystem.Web 과 달리 이것은 IDictionary<string, string[]>ASP.NET Core 1.x 또는 IDictionary<string, StringValues>ASP.NET Core 2.x 이상에서 유형의 사전을 반환 하므로 값은 문자열 모음입니다. 이것이 사전이 동일한 이름을 가진 여러 쿼리 문자열 매개 변수를 처리하는 방법입니다.

쿼리 문자열에 매개 변수를 추가하려면 다음에서 다른 방법을 사용할 수 있습니다 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);

.net core 2.2를 사용하면 다음을 사용하여 쿼리 문자열을 얻을 수 있습니다.

var request = HttpContext.Request;
var query = request.query;
foreach (var item in query){
   Debug.WriteLine(item) 
}

다음과 같이 키 : 값 쌍 모음을 얻을 수 있습니다.

[0] {[companyName, ]}
[1] {[shop, ]}
[2] {[breath, ]}
[3] {[hand, ]}
[4] {[eye, ]}
[5] {[firstAid, ]}
[6] {[eyeCleaner, ]}

절대 URI를 가져와 ASP.NET Core 패키지 만 사용하여 쿼리 문자열을 조작하는 가장 쉽고 직관적 인 방법은 몇 가지 간단한 단계로 수행 할 수 있습니다.

패키지 설치

PM> 설치 패키지 Microsoft.AspNetCore.WebUtilities
PM> 설치 패키지 Microsoft.AspNetCore.Http.Extensions

중요한 수업

그것들을 지적하기 위해 우리가 사용할 두 가지 중요한 클래스 인 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; }

This discussion on GitHub points to it as well.


This function return Dictionary<string, string> and does not use Microsoft.xxx for compatibility

Accepts parameter encoding in both sides

Accepts duplicate keys (return last value)

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

It's important to note that in the time since the top answer has been flagged as correct that Microsoft.AspNetCore.WebUtilities has had a major version update (from 1.x.x to 2.x.x).

That said, if you're building against netcoreapp1.1 you will need to run the following, which installs the latest supported version 1.1.2:

Install-Package Microsoft.AspNetCore.WebUtilities -Version 1.1.2


I use this as extention method, works with any number of params:

public static string AddOrReplaceQueryParameter(this HttpContext c, params string[] nameValues)
    {
        if (nameValues.Length%2!=0)
        {
            throw new Exception("nameValues: has more parameters then values or more values then parameters");
        }
        var qps = new Dictionary<string, StringValues>();
        for (int i = 0; i < nameValues.Length; i+=2)
        {
            qps.Add(nameValues[i], nameValues[i + 1]);
        }
        return c.AddOrReplaceQueryParameters(qps);
    }

public static string AddOrReplaceQueryParameters(this HttpContext c, Dictionary<string,StringValues> pvs)
    {
        var request = c.Request;
        UriBuilder uriBuilder = new UriBuilder
        {
            Scheme = request.Scheme,
            Host = request.Host.Host,
            Port = request.Host.Port ?? 0,
            Path = request.Path.ToString(),
            Query = request.QueryString.ToString()
        };

        var queryParams = QueryHelpers.ParseQuery(uriBuilder.Query);

        foreach (var (p,v) in pvs)
        {
            queryParams.Remove(p);
            queryParams.Add(p, v);
        }

        uriBuilder.Query = "";
        var allQPs = queryParams.ToDictionary(k => k.Key, k => k.Value.ToString());
        var url = QueryHelpers.AddQueryString(uriBuilder.ToString(),allQPs);

        return url;
    }

Next and prev links for example in a view:

var next = Context.Request.HttpContext.AddOrReplaceQueryParameter("page",Model.PageIndex+1+"");

var prev = Context.Request.HttpContext.AddOrReplaceQueryParameter("page",Model.PageIndex-1+"");

참고URL : https://stackoverflow.com/questions/29992848/parse-and-modify-a-query-string-in-net-core

반응형