So überprüfen Sie, ob eine Uri-Zeichenfolge gültig ist

79

Wie überprüfen Sie, ob eine Uri-Zeichenfolge gültig ist (dass Sie sie dem Uri-Konstruktor zuführen können)?

Bisher habe ich nur Folgendes, aber aus offensichtlichen Gründen würde ich einen weniger brutalen Weg bevorzugen:

    Boolean IsValidUri(String uri)
    {
        try
        {
            new Uri(uri);
            return true;
        }
        catch
        {
            return false;
        }
    }

Ich habe Uri.IsWellFormedUriString ausprobiert, aber es scheint nicht alles zu gefallen, was Sie auf den Konstruktor werfen können. Zum Beispiel:

String test = @"C:\File.txt";
Console.WriteLine("Uri.IsWellFormedUriString says: {0}", Uri.IsWellFormedUriString(test, UriKind.RelativeOrAbsolute));
Console.WriteLine("IsValidUri says: {0}", IsValidUri(test));

Die Ausgabe wird sein:

Uri.IsWellFormedUriString says: False
IsValidUri says: True

Update / Antwort

Der Uri-Konstruktor verwendet standardmäßig die Art Absolute. Dies verursachte eine Diskrepanz, als ich versuchte, Uri.TryCreate und den Konstruktor zu verwenden. Sie erhalten das erwartete Ergebnis, wenn Sie sowohl für den Konstruktor als auch für TryCreate mit UriKind übereinstimmen.

Manuel
quelle

Antworten:

80

Ein wohlgeformter URI impliziert die Konformität mit bestimmten RFCs. Der lokale Pfad in Ihrem Beispiel stimmt nicht mit diesen überein. Lesen Sie mehr in der IsWellFormedUriStringDokumentation.

Ein falsches Ergebnis dieser Methode bedeutet nicht, dass die UriKlasse die Eingabe nicht analysieren kann. Die URI-Eingabe ist möglicherweise nicht RFC-konform, kann jedoch eine gültige URI sein.

Update : Und um Ihre Frage zu beantworten - wie die Uri-Dokumentation zeigt, gibt es eine statische Methode TryCreate, die genau versucht, was Sie wollen, und true oder false zurückgibt (und die tatsächliche UriInstanz, wenn true).

Franci Penov
quelle
Die Frage lautet: "Wie überprüfen Sie, ob eine Uri-Zeichenfolge gültig ist (dass Sie sie dem Uri-Konstruktor zuführen können)?"
Manuel
1
TryCreate sagt Ihnen nicht wirklich, ob eine Zeichenfolge vom Konstruktor akzeptiert wird. Siehe Update.
Manuel
@Manuel: Das macht überhaupt keinen Sinn - das Ergebnis TryCreateund der UriKonstruktor sollten identisch sein - versuchen Sie, das zu übergeben, wofür UriKindSie es getan haben TryCreate.
BrokenGlass
1
Du hast recht. Der Konstruktor verwendet die Standardart Absolut. Vielen Dank.
Manuel
3
Laut .Net-Quellen enthält die IsWellFormedUriString-Methode den TryCreate-Methodenaufruf sowie zusätzliche Überprüfungen . Daher bevorzuge ich die Verwendung der IsWellFormedUriString-Methode als leistungsfähiger für solche Aufgaben.
Igor Kustov
43

Da die akzeptierte Antwort kein explizites Beispiel enthält, finden Sie hier einen Code zum Überprüfen von URIs in C #:

Uri outUri;

if (Uri.TryCreate("ThisIsAnInvalidAbsoluteURI", UriKind.Absolute, out outUri)
   && (outUri.Scheme == Uri.UriSchemeHttp || outUri.Scheme == Uri.UriSchemeHttps))
{
    //Do something with your validated Absolute URI...
}
DiscDev
quelle
2
Vertraue nicht der Uri.TryCreate Funktion! Dies erlaubt auch schlechte URLs. Versuchen Sie dies 'http: // http: // google.com/page' (Leerzeichen entfernen). Diese URL übergibt die TryCreate-Funktion, ist jedoch falsch.
No1Lives4Ever
5
@ No1Lives4Ever Sie haben Recht, dass es als gültig analysiert, was Sie erwähnt haben, aber dies ist technisch nicht falsch. Die Erklärung auf Englisch: Stellen Sie mithilfe des http-Protokolls ( http: // ) eine Verbindung zum DNS-Eintrag für "http" (http: // ** http **) über einen expliziten (aber weggelassenen) Port ( http **: *) her *) - also nehme ich die Standardeinstellung für das Protokoll an; Sie haben einen leeren Ordner der ersten Ebene ( http : ** // **) angegeben, aber ich weiß, was Sie gemeint haben;) gefolgt von einem Pfadsegment "google.com" ( http: / ** google.com / **) und dann die Ressource "Seite" ( http://google.com ** Seite **)
mlhDev
9

Angenommen, wir möchten nur absolute URI- und HTTP-Anforderungen unterstützen, dann ist hier eine Funktion, die das tut, was Sie wollen:

public static bool IsValidURI(string uri)
{
    if (!Uri.IsWellFormedUriString(uri, UriKind.Absolute))
        return false;
    Uri tmp;
    if (!Uri.TryCreate(uri, UriKind.Absolute, out tmp))
        return false;
    return tmp.Scheme == Uri.UriSchemeHttp || tmp.Scheme == Uri.UriSchemeHttps;
}
cdiggins
quelle
1
Die zweite Prüfung ist erforderlich, um die dritte (und letzte) Prüfung zu ermöglichen. Ohne es gibt es keine tmp. Der erste Schritt ist in diesem Fall wohl überflüssig ...
Joe
1

In meinem Fall wollte ich nur den Uri testen, ich möchte die Anwendung, die den Uri testet, nicht verlangsamen.

Boolean IsValidUri(String uri){
  return Uri.IsWellFormedUriString(uri, UriKind.Absolute);
}
Glauber Rodrigues
quelle
0

In Ihrem Fall ist das uri-Argument ein absoluter Pfad, der sich auf einen Dateispeicherort bezieht, sodass gemäß dem Dokument der Methode false zurückgegeben wird. Beziehen Sie sich darauf

Vijay Sirigiri
quelle
Ich verwende UriKind.RelativeOrAbsolute, also sollte es keine Rolle spielen. So oder so funktioniert es nicht mit UriKind.Relative oder UriKind.Absolute, also kein Glück.
Manuel