クエリ文字列部分も含む可能性のある URL があります。クエリ文字列が空であるか、複数の項目がある可能性があります。
クエリ文字列内のアイテムの 1 つを置換するか、アイテムがまだ存在しない場合は追加します。
完全な URL を持つ URI オブジェクトがあります。
私の最初のアイデアは、正規表現といくつかの文字列マジックを使用することでした。
しかし、少し不安定なようです。フレームワークにクエリ文字列ビルダー クラスがあるのではないでしょうか?
クエリ文字列部分も含む可能性のある URL があります。クエリ文字列が空であるか、複数の項目がある可能性があります。
クエリ文字列内のアイテムの 1 つを置換するか、アイテムがまだ存在しない場合は追加します。
完全な URL を持つ URI オブジェクトがあります。
私の最初のアイデアは、正規表現といくつかの文字列マジックを使用することでした。
しかし、少し不安定なようです。フレームワークにクエリ文字列ビルダー クラスがあるのではないでしょうか?
これはよりエレガントなソリューションであることがわかりました
var qs = HttpUtility.ParseQueryString(Request.QueryString.ToString());
qs.Set("item", newItemValue);
Console.WriteLine(qs.ToString());
次の 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
私は次の方法を使用します:
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();
}
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;
これは本当にうまくいくようです。
多分あなたはSystem.UriBuilder
クラスを使うことができます。プロパティがありQuery
ます。
いいえ、フレームワークには既存の QueryStringBuilder クラスはありませんが、通常、HTTP 要求内のクエリ文字列情報は、プロパティNameValueCollection
を介して反復可能および検索可能として利用できRequest.Querystring
ます。
ただし、オブジェクトから開始するため、オブジェクトのプロパティをUri
使用してクエリ文字列部分を取得する必要があります。これにより、次の形式の文字列が生成されます。Query
Uri
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
クラス。
次のコードを使用して、現在のリクエスト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();
}
私はセレブラスに同意します。KISSの原則に固執すると、クエリ文字列があり、
string querystring = myURI.Query;
探しているものと、それを置き換えたいものを知っています。
したがって、次のようなものを使用します:-
if (querystring == "")
myURI.Query += "?" + replacestring;
else
querystring.replace (searchstring, replacestring); // not too sure of syntax !!
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;
}
}
}
少し前に同様の質問に答えました。基本的に、最良の方法は class を使用することです。HttpValueCollection
これQueryString
は実際にはプロパティですが、残念ながら .NET フレームワークの内部にあります。Reflector を使用してそれを取得できます (そして Utils クラスに配置できます)。このようにして、クエリ文字列を NameValueCollection のように操作できますが、URL のエンコード/デコードの問題はすべて処理されます。
HttpValueCollection
extendsNameValueCollection
であり、エンコードされたクエリ文字列 (アンパサンドと疑問符を含む) を受け取るコンストラクターを持ち、ToString()
メソッドをオーバーライドして、基になるコレクションからクエリ文字列を後で再構築します。