8

I'm using the HttpClient. I'm posting with web form parameters. One of the values (not name) is a foreign Swedish character ö , #246; ö ASCII: Latin Small Letter O Umlaut

Manually, IE, Firefox and Chrome all convert this character to S%F6k and everything works fine. However VS 2012 C# release converts it (via FormUrlEncodedContent(dict)) to %C3%B6

Is there a way to tell VS 2012 to convert it, to the friendly S%F6k (and still use HttpClient)?

I've attached most of the code, which may help others (cookies, proxy, etc...)

// Create Handler
var handler = new HttpClientHandler();

// Cookies
var cc = new CookieContainer();
handler.CookieContainer = cc;

// Proxy - for fiddler
WebProxy proxy = new WebProxy();
proxy.Address = new Uri("http://localhost:8888");
handler.Proxy = proxy;

// Create the client
var client = new HttpClient(handler);

var request4 = new HttpRequestMessage();

client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("Accept", "text/html, application/xhtml+xml, */*");
client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
client.DefaultRequestHeaders.Add("Accept-Language", "en-US,en;q=0.8,sv-SE;q=0.5,sv;q=0.3");
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

// Form Data
var dict4 = new Dictionary<string, string>
{
    { "page", "kantlista" },
    { "kod", "A0004n" },
    { "termin", "H12" },
    { "anmkod", "17113" },
    { "urval", "ant" },
    { "listVal", "namn" },
    { "method", "Sök" } // S%F6k
}; // dict

request4.Content = new FormUrlEncodedContent(dict4);

var value4 = new FormUrlEncodedContent(dict4);
string uri4 = "https://www.ltu.se/ideal/ListaKursant.do";
var response4 = await client.PostAsync(uri4, value4);
response4.Headers.Add("Cache-Control", "no-cache")
response4.EnsureSuccessStatusCode();
string responseBody4 = await response4.Content.ReadAsStringAsync();
Charlieface
  • 52,284
  • 6
  • 19
  • 43
Todd Booth
  • 267
  • 1
  • 3
  • 12

3 Answers3

12

FormUrlEncodedContent class encode form data in utf8 encoding.
try ByteArrayContent class and HttpUtility.UrlEncode(String, Encoding) to encode.

Bakudan
  • 19,134
  • 9
  • 53
  • 73
Tyler Tsai
  • 136
  • 2
  • 3
  • 3
    This worked for me. But `HttpUtility.UrlEncode("!@$#%", Encoding.UTF8)` yielded different results than `FormUrlEncodedContent` did, I wonder why. – Conrad Clark Oct 30 '14 at 12:13
4

Just to complete @TylerTsai's answer

Replace

var dict = new Dictionary<string, string>();
dict.Add("param1", value1);
dict.Add("param1", value2);

var response = await httpClient.PostAsync(endpoint, new FormUrlEncodedContent(dict));

With

 string postData = HttpUtility.UrlEncode(
       $"param1={value1}&param2={value2}",Encoding.GetEncoding(myEncoding));
 byte[] data = System.Text.Encoding.GetEncoding(myEncoding).GetBytes(postData);
 ByteArrayContent content = new ByteArrayContent(data);
 content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
 
 var response = await httpClient.PostAsync(endpoint, content);
pedrofb
  • 37,271
  • 5
  • 94
  • 142
  • Pretty sure that would cause a runtime error - you are adding key "param1" to a `Dictionary` twice... – NetMage Oct 04 '22 at 19:27
0

With this small adjustment you can keep your dictionary

   var postEncoding= "ISO-8859-1";
    var dict4 = new Dictionary<string, string>
    {
        { "page", "kantlista" },
        { "kod", "A0004n" },
        { "termin", "H12" },
        { "anmkod", "17113" },
        { "urval", "ant" },
        { "listVal", "namn" },
        { "method", "Sök" } // S%F6k
    }; // dict
    
    
string postData = HttpUtility.UrlEncode(string.Join("&", dict4.Select(kvp => $"{kvp.Key}={kvp.Value}")) ,Encoding.GetEncoding(postEncoding));
    
byte[] data = Encoding.GetEncoding(postEncoding).GetBytes(postData);
ByteArrayContent content = new ByteArrayContent(data);
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
     
var response = await httpClient.PostAsync(endpoint, content);