Wie überprüfe ich, ob eine Zeichenfolge eine gültige HTTP-URL ist?


251

Es gibt die Methoden Uri.IsWellFormedUriStringund Uri.TryCreate, aber sie scheinen truefür Dateipfade usw. zurückzukehren.

Wie überprüfe ich, ob eine Zeichenfolge eine gültige (nicht unbedingt aktive) HTTP-URL für Zwecke der Eingabevalidierung ist?


Verwenden Sie regex.IsMatch überhaupt nicht, um die URL zu validieren. Kann CPU töten. stackoverflow.com/questions/31227785/…
inesmar

Antworten:


452

Versuchen Sie dies, um HTTP-URLs uriNamezu überprüfen ( ist der URI, den Sie testen möchten):

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
    && uriResult.Scheme == Uri.UriSchemeHttp;

Oder wenn Sie sowohl HTTP- als auch HTTPS-URLs als gültig akzeptieren möchten (gemäß J0e3gans Kommentar):

Uri uriResult;
bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) 
    && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

6
Sollte dies uriResult.Scheme anstelle von uriName.Scheme lauten? Ich verwende die Überladung von TryCreate, bei der String anstelle von Uri als erster Parameter verwendet wird.

7
Möglicherweise möchten Sie dem uriResult.Scheme == ... weitere Bedingungen hinzufügen. Insbesondere https. Es hängt davon ab, wofür Sie das brauchen, aber diese kleine Änderung war alles, was ich brauchte, damit es perfekt für mich funktioniert.
Fiarr

11
Um den Kommentar von @ Fiarr zu verdeutlichen, ist die "kleine Änderung", die erforderlich ist, um HTTPS zusätzlich zu den HTTP-URLs zu berücksichtigen, folgende:bool result = Uri.TryCreate(uriName, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps;
J0e3gan

3
Dieser Weg schlägt für URLs wie abcde fehl . Es heißt, dies sei eine gültige URL.
Kailash P

7
Es sieht so aus, als ob diese Technik 22 von 75 Tests nicht besteht. Dotnetfiddle.net/XduN3A
whitneyland

98

Diese Methode funktioniert sowohl in http als auch in https einwandfrei. Nur eine Zeile :)

if (Uri.IsWellFormedUriString("https://www.google.com", UriKind.Absolute))

MSDN: IsWellFormedUriString


13
Dies wird return true für Nicht-HTTP - URIs (dh andere Regelung wie file://oder ldap://diese Lösung mit einer Prüfung gegen die Regelung gekoppelt werden soll - z. B.if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps) ...
Kringel

Ist dieser RFC3986 kompatibel?
Marcus

3
@Squiggle Genau das möchte ich überprüfen, alles seit ich einen Downloader mache. Diese Antwort ist also die beste Methode für mich.
Beyondo

24
    public static bool CheckURLValid(this string source)
    {
        Uri uriResult;
        return Uri.TryCreate(source, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp;
    }

Verwendung:

string url = "htts://adasd.xc.";
if(url.CheckUrlValid())
{
  //valid process
}

UPDATE: (einzelne Codezeile) Danke @GoClimbColorado

public static bool CheckURLValid(this string source) => Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps;

Verwendung:

string url = "htts://adasd.xc.";
if(url.CheckUrlValid())
{
  //valid process
}

Dies scheint nicht mit WWW-URLs umzugehen. IE: www.google.com wird als ungültig angezeigt.
Zauber Paracelsus

6
@ZauberParacelsus "www.google.com" ist ungültig. Der URL-Mittelwert sollte mit "http", "ftp", "file" usw. beginnen. Die Zeichenfolge sollte "http: // www.google.com" ohne Leerzeichen sein
Erçin Dedeoğlu

1
Heute kann der out-Parameter eine Verbesserung Uri.TryCreate(source, UriKind.Absolute, out Uri uriResult) && uriResult.Scheme == Uri.UriSchemeHttps
bewirken

11

Alle Antworten hier entweder die Möglichkeit , URLs mit anderen Systemen (zB file://, ftp://) oder ablehnen Menschen lesbaren URLs , die mit nicht starten http://oder https://(zB www.google.com) , die nicht gut ist , wenn sie mit Benutzereingaben zu tun .

So mache ich das:

public static bool ValidHttpURL(string s, out Uri resultURI)
{
    if (!Regex.IsMatch(s, @"^https?:\/\/", RegexOptions.IgnoreCase))
        s = "http://" + s;

    if (Uri.TryCreate(s, UriKind.Absolute, out resultURI))
        return (resultURI.Scheme == Uri.UriSchemeHttp || 
                resultURI.Scheme == Uri.UriSchemeHttps);

    return false;
}

Verwendung:

string[] inputs = new[] {
                          "https://www.google.com",
                          "http://www.google.com",
                          "www.google.com",
                          "google.com",
                          "javascript:alert('Hack me!')"
                        };
foreach (string s in inputs)
{
    Uri uriResult;
    bool result = ValidHttpURL(s, out uriResult);
    Console.WriteLine(result + "\t" + uriResult?.AbsoluteUri);
}

Ausgabe:

True    https://www.google.com/
True    http://www.google.com/
True    http://www.google.com/
True    http://google.com/
False

1
Dies lässt einzelne Wörter wie "mooooooooo" durch, aber in Verbindung mit Uri verwendet. IsWellFormedUriString könnte gut sein
Epirocks

@Epirocks Das ist ein guter Punkt. Das Problem ist, dass http://moooooooooes sich tatsächlich um einen gültigen Uri handelt. Daher können Sie Uri.IsWellFormedUriStringnach dem Einfügen von "http: //" nicht nachsehen, und wenn Sie vorher nachsehen, wird alles, was kein a Schemehat, abgelehnt. Vielleicht können wir s.Contains('.')stattdessen nachsehen.
Ahmed Abdelhameed

moooooo an sich sieht nicht wie eine URL aus, da es kein Protokoll enthält. Was ich getan habe, war, Ihren Regex-Match-Anruf herauszunehmen und ihn auch mit IsWellFormedUriString zu bearbeiten.
Epirocks

@Epirocks Genau! Das Problem ist, dass wenn Sie IsWellFormedUriStringvor dem Hinzufügen von verwenden http://, Dinge wie ablehnen google.comund wenn Sie es nach dem Hinzufügen von verwenden http://, wird es immer noch true für zurückgeben http://mooooooooo. Aus diesem Grund habe ich vorgeschlagen, zu überprüfen, ob die Zeichenfolge .stattdessen eine enthält .
Ahmed Abdelhameed

Das ist sowieso in Ordnung für mich. Ich möchte keine URL ohne http oder https akzeptieren. Also benutze ich zuerst IsWellFormedUriString und dann deine Funktion ohne Regex. bool bResult = (Uri.IsWellFormedUriString (s, UriKind.Absolute) && ValidHttpURL (s, out uriResult)); Danke
Epirocks

5

Danach können Uri.TryCreateSie überprüfen Uri.Scheme, ob es sich um HTTP (s) handelt.


3

Versuch das:

bool IsValidURL(string URL)
{
    string Pattern = @"^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$";
    Regex Rgx = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
    return Rgx.IsMatch(URL);
}

Es akzeptiert URL wie folgt:

  • http (s): //www.example.com
  • http (s): //stackoverflow.example.com
  • http (s): //www.example.com/page
  • http (s): //www.example.com/page? id = 1 & product = 2
  • http (s): //www.example.com/page#start
  • http (s): //www.example.com: 8080
  • http (s): //127.0.0.1
  • 127.0.0.1
  • www.example.com
  • example.com

2

Dies würde bool zurückgeben:

Uri.IsWellFormedUriString(a.GetAttribute("href"), UriKind.Absolute)

2
Ich denke, das OP erwähnte speziell, er mag Uri.IsWellFormedUriString nicht, da es für Dateipfade wahr ist. Haben Sie eine Lösung für dieses Problem?
Isantipov

1
Uri uri = null;
if (!Uri.TryCreate(url, UriKind.Absolute, out uri) || null == uri)
    return false;
else
    return true;

Hier urlist die Zeichenfolge, die Sie testen müssen.


3
null == URL-Prüfung ist schrecklich redundant
JSON

0
bool passed = Uri.TryCreate(url, UriKind.Absolute, out Uri uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps)

Ihre Antwort kam in Posts von geringerer Qualität. Bitte geben Sie eine Erklärung an, obwohl Ihr Code selbsterklärend ist.
Harsha Biyani
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.