web-dev-qa-db-fra.com

C # HttpWebRequest de type "application / x-www-form-urlencoded" - comment envoyer le caractère '&' dans le corps du contenu?

J'écris une petite application connectée à l'API en C #.

Je me connecte à une API qui a une méthode qui prend une longue chaîne, le contenu d'un fichier de calendrier (ics).

Je le fais comme ça:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL);
request.Method = "POST";
request.AllowAutoRedirect = false;
request.CookieContainer = my_cookie_container;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.ContentType = "application/x-www-form-urlencoded";

string iCalStr = GetCalendarAsString();

string strNew = "&uploadfile=true&file=" + iCalStr;

using (StreamWriter stOut = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII))
 {
     stOut.Write(strNew);
     stOut.Close();
 }

Cela semble très bien fonctionner, jusqu'à ce que j'ajoute du code HTML spécifique dans mon calendrier.

Si j'ai un "& nbsp" quelque part dans mon calendrier (ou similaire), le serveur n'obtient que toutes les données jusqu'au point "&", donc je suppose que le "&" le fait ressembler à n'importe quoi après que ce point appartient à un nouveau paramètre?

Comment puis-je réparer cela?

32
nelshh

Étant donné que votre type de contenu est application/x-www-form-urlencoded vous devrez encoder le corps POST, surtout s'il contient des caractères comme & qui ont une signification particulière dans un formulaire.

Essayez de passer votre chaîne via HttpUtility.UrlEncode avant de l'écrire dans le flux de demande.

Voici quelques liens pour référence.

25
Andy White

Installez d'abord " Microsoft ASP.NET Web API Client " package nuget:

  PM > Install-Package Microsoft.AspNet.WebApi.Client

Utilisez ensuite la fonction suivante pour publier vos données:

public static async Task<TResult> PostFormUrlEncoded<TResult>(string url, IEnumerable<KeyValuePair<string, string>> postData)
{
    using (var httpClient = new HttpClient())
    {
        using (var content = new FormUrlEncodedContent(postData))
        {
            content.Headers.Clear();
            content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            HttpResponseMessage response = await httpClient.PostAsync(url, content);

            return await response.Content.ReadAsAsync<TResult>();
        }
    }
}

Et voici comment l'utiliser:

TokenResponse tokenResponse = 
    await PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData);

ou

TokenResponse tokenResponse = 
    (Task.Run(async () 
        => await PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData)))
        .Result

ou (non recommandé)

TokenResponse tokenResponse = 
    PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData).Result;
36
Tohid

Tant que le serveur permet au caractère esperluette d'être POSTÉ (tout ne fait pas car il peut être dangereux), tout ce que vous devriez avoir à faire est de coder l'URL du caractère. Dans le cas d'une esperluette, vous devez remplacer le caractère par %26.

.NET fournit cependant un bon moyen d'encoder la chaîne entière:

string strNew = "&uploadfile=true&file=" + HttpUtility.UrlEncode(iCalStr);
8
Justin Niessner