2
votes

.Net HttpClient URI invalide: la chaîne Uri est trop longue

Le code ci-dessous est utilisé pour envoyer des e-mails via l'API pardot.

if (ConfigurationManager.AppSettings.Count > 0)
        {
            uri = ConfigurationManager.AppSettings["PardotURI"].ToString() + "email/version/4/do/send/prospect_email/" + email;
            uri += "?user_key=" + ConfigurationManager.AppSettings["PardotUserKey"].ToString();
            uri += "&api_key=" + GetAPIKey() + "&campaign_id=" + GetPardotCampaign("Capis News");
            uri += "&from_email=" + ConfigurationManager.AppSettings["FromEmail"].ToString();
            uri += "&from_name=" + ConfigurationManager.AppSettings["FromName"].ToString();
            uri += "&name=FlyNews - " + DateTime.Now.ToString("MM/dd/yyy h:mm tt");
            uri += "&subject=CAPIS: Client Holdings News " + DateTime.Today.ToString("MM/dd/yyyy");
        }

        try
        {
            MultipartFormDataContent data = new MultipartFormDataContent();

            data.Add(new StringContent(htmlContent), "html_content");
            data.Add(new StringContent(textContent), "text_content");

            await client.PostAsync(uri, data);
            client.Dispose();
        }
        catch(Exception ex)

Cela fonctionnait très bien jusqu'à ce que je remarque qu'il y a quelques jours, il a commencé à lever l'exception suivante. Malheureusement, ce n'est pas cohérent car il enverra 30/40 e-mails mais lancera des exceptions pour les 10 autres, et le nombre d'exceptions chaque jour a été différent et pour différentes personnes. Je sais que les données que j'envoie dans le formulaire multipartite sont volumineuses, mais cela ne devrait pas faire partie de l'URI et à moins que quelqu'un n'ait un e-mail de 1500 caractères, l'URI ne devrait jamais être trop long. Quelqu'un a-t-il une idée de ce qui peut se passer? J'apprécie toute aide.

System.UriFormatException: URI non valide: la chaîne Uri est trop longue. à System.UriHelper.EscapeString (String input, Int32 start, Int32 end, Char [] dest, Int32 & destPos, Boolean isUriString, Char force1, Char force2, Char rsvd) à System.Uri.EscapeDataString (String stringToEscape) à System.Net .Http. .PardotDataAccess.d__9.MoveNext ()


0 commentaires

3 Réponses :


-1
votes

J'ai eu un problème similaire lors de l'utilisation de "MultipartFormDataContent" et je ne recommanderais pas de l'utiliser.

Maintenant, j'utilise JSON pour cela.

Vous trouverez peut-être plus d'informations ici: https://stackoverflow.com/a/38440832/6488079

J'espère que cela aide!


2 commentaires

L'OP appelle une API tierce. Il ne peut pas simplement utiliser JSON, il doit utiliser ce que l'API prend en charge.


En fait, tu as raison. L '"api pardot" semble n'accepter que les paramètres de requête et j'aurais peut-être gardé à l'esprit ma propre expérience. Toujours le lien que j'ai fourni peut aider pour ce problème, en particulier ce commentaire: stackoverflow.com/a/48393926/6488079



4
votes

Il s'agit d'un problème connu dans à peu près toutes les versions de .NET. Même si le message d'exception dit «URI non valide», vous remarquerez à partir de la trace de la pile qu'il est lancé depuis FormUrlEncodedContent . Le corps de la requête est donc le problème.

Une façon de contourner ce problème consiste à utiliser Flurl (clause de non-responsabilité: je suis l'auteur) pour faire la demande. J'ai explicitement corrigé ce problème dans l'implémentation de Flurl. Et en prime, il nettoiera considérablement votre code de création d'URL et de création de contenu:

await ConfigurationManager.AppSettings["PardotURI"]
    .AppendPathSegments("email/version/4/do/send/prospect_email", email)
    .SetQueryParams(new {
        user_key = ConfigurationManager.AppSettings["PardotUserKey"],
        pi_key = GetAPIKey() + "&campaign_id=" + GetPardotCampaign("Capis News");
        from_email = ConfigurationManager.AppSettings["FromEmail"],
        from_name = ConfigurationManager.AppSettings["FromName"],
        name = "FlyNews - " + DateTime.Now.ToString("MM/dd/yyy h:mm tt"),
        subject = "CAPIS: Client Holdings News " + DateTime.Today.ToString("MM/dd/yyyy")
    })
    .PostUrlEncodedAsync(new {
        html_content = htmlContent,
        text_content = textContent
    });


0 commentaires

-1
votes

Désolé, j'ai trouvé une solution pour moi le lendemain de la publication de ce message et j'ai oublié le message. J'ai changé les appels d'API en synchrones et je n'ai pas vu d'erreur depuis. Je pense que parce que l'API que je dois utiliser vous limite à 5 appels simultanés, peut-être que leur asynchrone a causé un nombre d'appels d'accès et donc des erreurs.


1 commentaires

Les détails de l'exception que vous avez publiés dans la question indiquent clairement que l'erreur se produit lors de la sérialisation du corps de la demande, ce qui se produit avant même que la demande ne soit envoyée. Cela n'aurait donc rien à voir avec les limites de débit ou la synchronisation vs asynchrone. Si vous ne voyez plus d'erreurs, c'est une pure coïncidence - vous n'avez pas créé de corps de requête de plus de 65 520 caractères ou vous êtes passé à une bibliothèque (synchrone) qui n'utilise pas Uri.EscapeDataString .