Ich habe eine Zeichenfolge in .NET, die eigentlich eine URL ist. Ich möchte einen einfachen Weg, um den Wert von einem bestimmten Parameter zu erhalten.
Normalerweise würde ich nur Request.Params["theThingIWant"]
, aber dieser String stammt nicht aus der Anfrage. Ich kann ein neues Uri
Element wie folgt erstellen:
Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);
Ich kann nutzen myUri.Query
, um die Abfragezeichenfolge abzurufen ... aber dann muss ich anscheinend einen regulären Weg finden, sie aufzuteilen.
Fehlt mir etwas Offensichtliches, oder gibt es keine eingebaute Möglichkeit, dies zu tun, ohne eine Art Regex zu erzeugen?
Verwende die statische ParseQueryString
Methode von System.Web.HttpUtility
Klasse, die NameValueCollection
zurückgibt.
Uri myUri = new Uri("http://www.example.com?param1=good¶m2=bad");
string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");
Überprüfen Sie die Dokumentation unter http://msdn.Microsoft.com/en-us/library/ms150046.aspx
Das ist wahrscheinlich was Sie wollen
var uri = new Uri("http://domain.test/Default.aspx?var1=true&var2=test&var3=3");
var query = HttpUtility.ParseQueryString(uri.Query);
var var2 = query.Get("var2");
Hier ist eine weitere Alternative, wenn Sie HttpUtility.ParseQueryString()
aus irgendeinem Grund nicht verwenden können oder möchten.
Dies ist so aufgebaut, dass es gegenüber "fehlerhaften" Abfragezeichenfolgen etwas tolerant ist, d. H. http://test/test.html?empty=
Wird zu einem Parameter mit einem leeren Wert. Der Anrufer kann die Parameter bei Bedarf überprüfen.
public static class UriHelper
{
public static Dictionary<string, string> DecodeQueryParameters(this Uri uri)
{
if (uri == null)
throw new ArgumentNullException("uri");
if (uri.Query.Length == 0)
return new Dictionary<string, string>();
return uri.Query.TrimStart('?')
.Split(new[] { '&', ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(parameter => parameter.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries))
.GroupBy(parts => parts[0],
parts => parts.Length > 2 ? string.Join("=", parts, 1, parts.Length - 1) : (parts.Length > 1 ? parts[1] : ""))
.ToDictionary(grouping => grouping.Key,
grouping => string.Join(",", grouping));
}
}
Test
[TestClass]
public class UriHelperTest
{
[TestMethod]
public void DecodeQueryParameters()
{
DecodeQueryParametersTest("http://test/test.html", new Dictionary<string, string>());
DecodeQueryParametersTest("http://test/test.html?", new Dictionary<string, string>());
DecodeQueryParametersTest("http://test/test.html?key=bla/blub.xml", new Dictionary<string, string> { { "key", "bla/blub.xml" } });
DecodeQueryParametersTest("http://test/test.html?eins=1&zwei=2", new Dictionary<string, string> { { "eins", "1" }, { "zwei", "2" } });
DecodeQueryParametersTest("http://test/test.html?empty", new Dictionary<string, string> { { "empty", "" } });
DecodeQueryParametersTest("http://test/test.html?empty=", new Dictionary<string, string> { { "empty", "" } });
DecodeQueryParametersTest("http://test/test.html?key=1&", new Dictionary<string, string> { { "key", "1" } });
DecodeQueryParametersTest("http://test/test.html?key=value?&b=c", new Dictionary<string, string> { { "key", "value?" }, { "b", "c" } });
DecodeQueryParametersTest("http://test/test.html?key=value=what", new Dictionary<string, string> { { "key", "value=what" } });
DecodeQueryParametersTest("http://www.google.com/search?q=energy+Edge&rls=com.Microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22",
new Dictionary<string, string>
{
{ "q", "energy+Edge" },
{ "rls", "com.Microsoft:en-au" },
{ "ie", "UTF-8" },
{ "oe", "UTF-8" },
{ "startIndex", "" },
{ "startPage", "1%22" },
});
DecodeQueryParametersTest("http://test/test.html?key=value;key=anotherValue", new Dictionary<string, string> { { "key", "value,anotherValue" } });
}
private static void DecodeQueryParametersTest(string uri, Dictionary<string, string> expected)
{
Dictionary<string, string> parameters = new Uri(uri).DecodeQueryParameters();
Assert.AreEqual(expected.Count, parameters.Count, "Wrong parameter count. Uri: {0}", uri);
foreach (var key in expected.Keys)
{
Assert.IsTrue(parameters.ContainsKey(key), "Missing parameter key {0}. Uri: {1}", key, uri);
Assert.AreEqual(expected[key], parameters[key], "Wrong parameter value for {0}. Uri: {1}", parameters[key], uri);
}
}
}
Sieht so aus, als ob Sie die Werte von myUri.Query
Durchlaufen und von dort aus analysieren sollten.
string desiredValue;
foreach(string item in myUri.Query.Split('&'))
{
string[] parts = item.Replace('?', '').Split('=');
if(parts[0] == "desiredKey")
{
desiredValue = parts[1];
break;
}
}
Ich würde diesen Code jedoch nicht verwenden, ohne ihn auf einer Reihe von fehlerhaften URLs zu testen. Es könnte bei einigen/allen der folgenden Probleme auftreten:
hello.html?
hello.html?valuelesskey
hello.html?key=value=hi
hello.html?hi=value?&b=c
@ Andrew und @ CZFox
Ich hatte den gleichen Fehler und stellte fest, dass der Grund dafür der folgende Parameter ist: http://www.example.com?param1
Und nicht param1
, Wie man es erwarten würde.
Durch Entfernen aller Zeichen vor und einschließlich des Fragezeichens wird dieses Problem behoben. Im Wesentlichen erfordert die Funktion HttpUtility.ParseQueryString
Nur einen gültigen Abfragezeichenfolgenparameter, der nur Zeichen nach dem Fragezeichen enthält, wie in:
HttpUtility.ParseQueryString ( "param1=good¶m2=bad" )
Mein Workaround:
string RawUrl = "http://www.example.com?param1=good¶m2=bad";
int index = RawUrl.IndexOf ( "?" );
if ( index > 0 )
RawUrl = RawUrl.Substring ( index ).Remove ( 0, 1 );
Uri myUri = new Uri( RawUrl, UriKind.RelativeOrAbsolute);
string param1 = HttpUtility.ParseQueryString( myUri.Query ).Get( "param1" );`
Sie können die folgende Problemumgehung verwenden, um auch mit dem ersten Parameter zu arbeiten:
var param1 =
HttpUtility.ParseQueryString(url.Substring(
new []{0, url.IndexOf('?')}.Max()
)).Get("param1");
Verwenden Sie .NET Reflector, um die FillFromString
-Methode von System.Web.HttpValueCollection
Anzuzeigen. Das gibt Ihnen den Code, den ASP.NET verwendet, um die Auflistung Request.QueryString
Zu füllen.
Oder wenn Sie die URL nicht kennen (um Hardcoding zu vermeiden, verwenden Sie AbsoluteUri
Beispiel ...
//get the full URL
Uri myUri = new Uri(Request.Url.AbsoluteUri);
//get any parameters
string strStatus = HttpUtility.ParseQueryString(myUri.Query).Get("status");
string strMsg = HttpUtility.ParseQueryString(myUri.Query).Get("message");
switch (strStatus.ToUpper())
{
case "OK":
webMessageBox.Show("EMAILS SENT!");
break;
case "ER":
webMessageBox.Show("EMAILS SENT, BUT ... " + strMsg);
break;
}
HttpContext.Current.Request.QueryString.Get("id");
Das ist eigentlich sehr einfach, und das hat bei mir funktioniert :)
if (id == "DK")
{
string longurl = "selectServer.aspx?country=";
var uriBuilder = new UriBuilder(longurl);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query["country"] = "DK";
uriBuilder.Query = query.ToString();
longurl = uriBuilder.ToString();
}
wenn Sie möchten, können Sie QueryString auf die Standardseite setzen. Die Standardseite ist Ihre aktuelle Seiten-URL. Sie können diesen Code ausprobieren:
string paramIl = HttpUtility.ParseQueryString(this.ClientQueryString).Get("city");
Für alle, die alle Abfragezeichenfolgen einer Zeichenfolge durchlaufen möchten
foreach (var item in new Uri(urlString).Query.TrimStart('?').Split('&'))
{
var subStrings = item.Split('=');
var key = subStrings[0];
var value = subStrings[1];
// do something with values
}