12
votes

Uri.trycreate jette uformatexception?

J'ai une méthode qui tente de créer une URI puis de le nettoyer (supprime des fragments, exclut certains domaines et des schémas de chaîne de requête, etc.). La méthode ressemble à ceci: xxx

Cette méthode fonctionne bien pendant des mois. Mais la nuit dernière, il a échoué. Uri.trycreate () a jeté une exception! Voici la trace de la pile: xxx

documentation pour uri.trycreate (URI, chaîne, sortie URI) dit que la valeur de retour est true En cas de succès, faux sinon, mais il est silencieux sur les exceptions. Toutefois, la documentation pour uri.trycreate (URI, URI, URI) dit:

Cette méthode construit l'URI, met il sous forme canonique et valide ce. Si une exception non gérée survient, Cette méthode l'attrape. Si tu veux créer une URI et obtenir des exceptions un des constructeurs d'URI.

La trace de la pile montre que l'exception a été lancée dans uri.trycreate (Uri, Uri, Out Uri) , qui, selon la documentation, ne devraient pas arriver.

C'est un événement très rare. J'utilise ce code pendant des mois, exécutant littéralement des milliards d'URL à travers elle et n'ont pas rencontré de problème jusqu'à présent. Malheureusement, je ne sais pas quelle combinaison de choses a causé le problème. J'espère construire un étui à essai indiquant l'erreur.

est-ce un bug connu dans uri.trycreate , ou je manque quelque chose?


3 commentaires

Savez-vous quelle url il essaie d'analyser qui causant l'échec?


Si je savais ça, je l'aurais posté.


Utilisez le réflecteur pour savoir ce que «trycreate» fait


3 Réponses :


3
votes

Maintenant que vous savez que cela peut échouer, prenons plus d'informations: xxx


2 commentaires

J'ai ajouté du code similaire à mon application. Malheureusement, cela pourrait être plusieurs jours (semaines ou mois) avant que l'erreur soit déclenchée. J'essaie de construire un cas de test.


D'accord. Notez que la partie importante est de capturer et d'afficher les deux paramètres d'entrée pour trycreate. Je parie que la réponse vous sautera lorsque vous le verrez, surtout que vous aurez également la trace de la pile.



21
votes

Ne veut pas attendre plusieurs mois pour que mon code rencontre à nouveau cette situation, j'ai passé du temps avec Ilasm pour comprendre ce que trycreate fait, puis un peu plus de temps à venir avec une manière Pour reproduire l'erreur.

La raison de l'accident dans uri.trycree (URI BASEURI, URI RelativeURI, OUT URI) semble être un BASEURI . Par exemple, le constructeur uri permet les éléments suivants: xxx

selon le RFC pour le mailto: URIS, qui ne devrait pas être autorisé. Et bien que le constructeur crée et renvoie un objet uri , essayant d'accéder à (certaines des) ses propriétés lancent uformatException . Par exemple, étant donné le code ci-dessus, cette ligne lancera une exception: xxx

Je trouve cela plutôt intéressant que la classe uri semble utiliser deux Différents algorithmes d'analyse: une utilisée pendant la construction, et l'une utilisée en interne pour obtenir les composants individuels.

transmettre ce non valide uri à trycreate entraînera le exception que j'ai décrit dans la question initiale. Le trycreate vérifie le paramètre baseuri pour null , mais je ne peux pas, j'imagine) le valider le contraire. Il doit supposer que si le paramètre est non nul, l'objet transduit est une instance URI URI . Mais à un moment donné de construire le résultat, trycreate tente d'obtenir les composants de baseuri et une exception est lancée.

Je ne peux pas dire que Mon programme a réellement rencontré un mailto: URL qui a été formatée de cette façon. Je peux dire avec un certain degré de certitude, cependant, qu'un objet URI non valide était la cause de l'accident dans mon programme, simplement parce que la trace de la pile d'exception de mon programme correspond à la trace de la pile à partir du programme de test . Il suffit de mettre, le bug est dans le constructeur URI (ainsi que dans les méthodes trycreate ) qui permettent à l'URI invalide à créer.

Vous pouvez suivre le Signaler de bogues sur Microsoft Connecter.


0 commentaires

-2
votes
 public static bool CheckUrlValid(string url)
    {
        Uri uriResult;
        bool result = Uri.TryCreate(url, UriKind.Absolute, out uriResult);
        if(result)
        {
            uriResult = new Uri(url);
            if (uriResult.Scheme == Uri.UriSchemeHttps || uriResult.Scheme == Uri.UriSchemeHttp)
                return true;
        }

        return false;
    }

3 commentaires

Cela semble bien fonctionner pour moi. Si vous essayez d'utiliser la variable URI sans l'initialiser, cela provoquera une erreur.


Bienvenue à Stackoverflow! Lorsque vous avez posté des réponses aux questions, veuillez publier plus que votre code. Expliquez-le, montre que c'est une utilisation, faites n'importe quoi pour rendre votre réponse aussi claire que possible, mais une réponse doit toujours être plus que celle du code. Merci et bonne chance!


Merci pour la pensée, mais c'est environ sept ans trop tard et ne répond pas vraiment à la question. Vous voyez, mon point était que uri.trycreate jetait une exception qu'il n'aurait pas dû lancer. Votre solution proposée ne voudrait pas aider. J'ai finalement identifié le problème à l'aide du code similaire à ce que John Saunders a proposé dans sa réponse. C'est-à-dire, attrapez l'exception et sortie l'URL qui a déclenché l'erreur.