19

クエリ文字列部分も含む可能性のある URL があります。クエリ文字列が空であるか、複数の項目がある可能性があります。

クエリ文字列内のアイテムの 1 つを置換するか、アイテムがまだ存在しない場合は追加します。

完全な URL を持つ URI オブジェクトがあります。

私の最初のアイデアは、正規表現といくつかの文字列マジックを使用することでした。

しかし、少し不安定なようです。フレームワークにクエリ文字列ビルダー クラスがあるのではないでしょうか?

4

10 に答える 10

50

これはよりエレガントなソリューションであることがわかりました

var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString());
qs.Set("item", newItemValue);
Console.WriteLine(qs.ToString());
于 2012-05-02T10:44:12.403 に答える
26

次の URL を取得します。 https://localhost/video?param1=value1

最初に、特定のクエリ文字列パラメーターを新しい値に更新します。

var uri = new Uri("https://localhost/video?param1=value1");
var qs = HttpUtility.ParseQueryString(uri.Query);
qs.Set("param1", "newValue2");

次に、プロパティを作成UriBuilderおよび更新Queryして、変更されたパラメーター値で新しい uri を生成します。

var uriBuilder = new UriBuilder(uri);
uriBuilder.Query = qs.ToString();
var newUri = uriBuilder.Uri;

newUriこれで、次の値 が得られました。https://localhost/video?param1=newValue2

于 2014-10-15T11:23:17.633 に答える
5

私は次の方法を使用します:

    public static string replaceQueryString(System.Web.HttpRequest request, string key, string value)
    {
        System.Collections.Specialized.NameValueCollection t = HttpUtility.ParseQueryString(request.Url.Query);
        t.Set(key, value);
        return t.ToString();
    }
于 2012-02-08T15:03:10.710 に答える
4
string link = page.Request.Url.ToString();

if(page.Request.Url.Query == "")
    link  += "?pageIndex=" + pageIndex;
else if (page.Request.QueryString["pageIndex"] != "")
{
    var idx = page.Request.QueryString["pageIndex"];
    link = link.Replace("pageIndex=" + idx, "pageIndex=" + pageIndex);
}
else 
    link += "&pageIndex=" + pageIndex;

これは本当にうまくいくようです。

于 2010-10-05T10:45:29.987 に答える
4

多分あなたはSystem.UriBuilderクラスを使うことができます。プロパティがありQueryます。

于 2009-04-21T12:33:07.013 に答える
3

いいえ、フレームワークには既存の QueryStringBuilder クラスはありませんが、通常、HTTP 要求内のクエリ文字列情報は、プロパティNameValueCollectionを介して反復可能および検索可能として利用できRequest.Querystringます。

ただし、オブジェクトから開始するため、オブジェクトのプロパティをUri使用してクエリ文字列部分を取得する必要があります。これにより、次の形式の文字列が生成されます。QueryUri

Uri myURI = new Uri("http://www.mywebsite.com/page.aspx?Val1=A&Val2=B&Val3=C");
string querystring = myURI.Query;

// Outputs: "?Val1=A&Val2=B&Val3=C". Note the ? prefix!
Console.WriteLine(querystring);

次に、この文字列をアンパサンド文字で分割して、異なるクエリ文字列パラメーターと値のペアに区別できます。次に、各パラメーターを「=」文字で再度分割して、キーと値に区別します。

最終的な目標は、特定のクエリ文字列キーを検索し、必要に応じてそれを作成することであるため、コレクションを簡単に検索できるコレクション (できれば一般的なもの) を (再) 作成する必要があります。NameValueCollectionクラス。

于 2009-04-21T12:21:55.870 に答える
2

次のコードを使用して、現在のリクエストURLのパラメーターの値を追加/置換しました。

    public static string CurrentUrlWithParam(this UrlHelper helper, string paramName, string paramValue)
    {
        var url = helper.RequestContext.HttpContext.Request.Url;
        var sb = new StringBuilder();

        sb.AppendFormat("{0}://{1}{2}{3}",
                        url.Scheme,
                        url.Host,
                        url.IsDefaultPort ? "" : ":" + url.Port,
                        url.LocalPath);

        var isFirst = true;

        if (!String.IsNullOrWhiteSpace(url.Query))
        {
            var queryStrings = url.Query.Split(new[] { '?', ';' });
            foreach (var queryString in queryStrings)
            {
                if (!String.IsNullOrWhiteSpace(queryString) && !queryString.StartsWith(paramName + "="))
                {
                    sb.AppendFormat("{0}{1}", isFirst ? "?" : ";", queryString);
                    isFirst = false;
                }
            }
        }

        sb.AppendFormat("{0}{1}={2}", isFirst ? "?" : ";", paramName, paramValue);

        return sb.ToString();
    }

多分これはこのトピックを見つけるときに他の人を助けるでしょう。

アップデート:

UriBuilderに関するヒントを見て、UriBuilder、StringBuilder、Linqを使用して2番目のバージョンを実行しました。

    public static string CurrentUrlWithParam(this UrlHelper helper, string paramName, string paramValue)
    {
        var url = helper.RequestContext.HttpContext.Request.Url;
        var ub = new UriBuilder(url.Scheme, url.Host, url.Port, url.LocalPath);

        // Query string
        var sb = new StringBuilder();
        var isFirst = true;
        if (!String.IsNullOrWhiteSpace(url.Query))
        {
            var queryStrings = url.Query.Split(new[] { '?', ';' });
            foreach (var queryString in queryStrings.Where(queryString => !String.IsNullOrWhiteSpace(queryString) && !queryString.StartsWith(paramName + "=")))
            {
                sb.AppendFormat("{0}{1}", isFirst ? "" : ";", queryString);
                isFirst = false;
            }
        }
        sb.AppendFormat("{0}{1}={2}", isFirst ? "" : ";", paramName, paramValue);
        ub.Query = sb.ToString();

        return ub.ToString();
    }
于 2011-10-14T08:34:14.930 に答える
1

私はセレブラスに同意します。KISSの原則に固執すると、クエリ文字列があり、

string querystring = myURI.Query; 

探しているものと、それを置き換えたいものを知っています。

したがって、次のようなものを使用します:-

if (querystring == "") 
  myURI.Query += "?" + replacestring; 
else 
  querystring.replace (searchstring, replacestring); // not too sure of syntax !!
于 2009-04-21T13:46:40.330 に答える
0
   public class QueryParams : Dictionary<string,string>
   {
       private Uri originolUrl;
       private Uri ammendedUrl;
       private string schemeName;
       private string hostname;
       private string path;

       public QueryParams(Uri url)
       {
           this.originolUrl = url;
           schemeName = url.Scheme;
           hostname = url.Host;
           path = url.AbsolutePath;
           //check uri to see if it has a query
           if (url.Query.Count() > 1)
           {
               //we grab the query and strip of the question mark as we do not want it attached
               string query = url.Query.TrimStart("?".ToArray());
               //we grab each query and place them into an array
               string[] parms = query.Split("&".ToArray());
               foreach (string str in parms)
               {
                   // we split each query into two strings(key) and (value) and place into array
                   string[] param = str.Split("=".ToArray());
                   //we add the strings to this dictionary
                   this.Add(param[0], param[1]);
               }
           }
       }


       public QueryParams Set(string paramName, string value)
       {

           if(this.ContainsKey(paramName))
           {
               //if key exists change value
               this[paramName] = value;
               return (this);
           }
           else
           {
               this.Add(paramName, value);
               return this;
           }
       }
       public QueryParams Set(string paramName, int value)
       {
           if (this.ContainsKey(paramName))
           {
               //if key exists change value
               this[paramName] = value.ToString();
               return (this);
           }
           else 
           {
               this.Add(paramName, value);
               return this;
           }
       }

       public void Add(string key, int value)
       {
           //overload, adds a new keypair
           string strValue = value.ToString();
           this.Add(key, strValue);
       }

       public override string ToString()
       {
           StringBuilder queryString = new StringBuilder();

           foreach (KeyValuePair<string, string> pair in this)
           {
               //we recreate the query from each keypair 
               queryString.Append(pair.Key + "=" + pair.Value + "&");
           }
           //trim the end of the query
           string modifiedQuery = queryString.ToString().TrimEnd("&".ToArray());

           if (this.Count() > 0)
           {
               UriBuilder uriBuild = new UriBuilder(schemeName, hostname);
               uriBuild.Path = path;
               uriBuild.Query = modifiedQuery;
               ammendedUrl = uriBuild.Uri;
               return ammendedUrl.AbsoluteUri;
           }
           else
           {
               return originolUrl.ToString();
           }
       }


       public Uri ToUri()
       {
          this.ToString();
          return ammendedUrl;
       }
   }
}
于 2015-11-17T11:53:41.760 に答える
0

少し前に同様の質問に答えました。基本的に、最良の方法は class を使用することです。HttpValueCollectionこれQueryStringは実際にはプロパティですが、残念ながら .NET フレームワークの内部にあります。Reflector を使用してそれを取得できます (そして Utils クラスに配置できます)。このようにして、クエリ文字列を NameValueCollection のように操作できますが、URL のエンコード/デコードの問題はすべて処理されます。

HttpValueCollectionextendsNameValueCollectionであり、エンコードされたクエリ文字列 (アンパサンドと疑問符を含む) を受け取るコンストラクターを持ち、ToString()メソッドをオーバーライドして、基になるコレクションからクエリ文字列を後で再構築します。

于 2009-04-21T12:26:50.943 に答える