applicationx-www-form-urlencoded with Httpwebrequest

Asked

Viewed 4,277 times

5

I’m making a system to authenticate the Token (derived from the credit card) next to Cielo. This token has special characters like +

Cielo receives the data via XML. I made the following code to send:

 private String sendHttpRequest(String message)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endpoint);

    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    using (Stream stream = request.GetRequestStream())
    {
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] bytes = encoding.GetBytes("mensagem=" + message);

        stream.Write(bytes, 0, bytes.Length);
    }


    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    string result;

    using (Stream stream = response.GetResponseStream())
    {
        using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
        {
            result = reader.ReadToEnd();
        }
    }

    return result.ToString();
}

However the token arrives in a different way in Cielo returning me Token not found, being that it generated the Token. When contacting the support of why is their response:

The error occurs when sending the token request without converting URL-encoding, i.e., the special characters (for example +) is interpreted as spaces by the platform. This is because the platform receives XML in an HTTP request parameter, using the content-type applicationx-www-form-urlencoded. Technologies such as Java (Apache Httpcomponenthttpclient) perform this conversion automatically, becoming transparent to the developer. The establishment should evaluate and adjust the encoding (Urlencode) in its solution, otherwise other special characters will display the same problem.

I believe my code is correct when reading that url I tried to do something with Httputility.Urlencode(message); ex:

var t = HttpUtility.UrlEncode(message);
byte[] bytes = encoding.GetBytes ("mensagem=" + t);

But same mistake, before I call there and complain to Cielo I would like some help, because I may be making some mistake.

Is there a way I copy the Bytes and try to simulate this post by some browser plugin? like I do with Chrome’s 'Simple REST Client' plugin?

Can I debug and visualize something that I can help?

NOTE: When the token is without these special characters, the same code above works perfectly.

2 answers

4

Dorathoto, initially I can’t see a problem with your code, what I can suggest is that you try to make this request using the Webapi Client.

Install the following package:

Microsoft ASP.NET Web API 2.2 Client

Then you can use the following code:

private async Task<string> sendHttpRequest(string message)
{
    var data = new Dictionary<string, string>();
    data.Add("mensagem", message);

    using (var cliente = new HttpClient())
    {
        using (var conteudo = new FormUrlEncodedContent(data))
        {
            conteudo.Headers.Clear();
            conteudo.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            var response = await cliente.PostAsync("minha url", conteudo);
            return await response.Content.ReadAsAsync<string>();
        }
    }
}

you can also use a StringContent in place of FormUrlEncodedContent, if you need to define an Encode other than ISO-8859-1:

private async Task<string> sendHttpRequest(string mensagem)
{
    var data = new Dictionary<string, string>();
    data.Add("mensagem", mensagem);

    using (var cliente = new HttpClient())
    {
        var chaves = new string[data.Count];
        var itens = new string[data.Count];

        data.Keys.CopyTo(chaves, 0);
        for (var indice = 0; indice < itens.Length; indice++)
        {
            var chave = chaves[indice];
            itens[indice] = chave + '=' + data[chave];
        }

        var encoded = Uri.EscapeDataString(String.Join("&", itens)).Replace("%20", "+");
        using (var conteudo = new StringContent(encoded, Encoding.UTF8, "application/x-www-form-urlencoded"))
        {
            var response = await cliente.PostAsync("minha url", conteudo);
            return await response.Content.ReadAsAsync<string>();
        }
    }
}

then you can call this method as follows:

var mensagem = "Hello Wolrd";
var response = Task.Run<string>(async () => await sendHttpRequest(mensagem)).Result;

another alternative would be to try to use a StreamWriter instead of writing directly to Stream of your request

replace your code snippet similar to the one below:

using (Stream stream = request.GetRequestStream ()) {
    UTF8Encoding encoding = new UTF8Encoding ();
    byte[] bytes = encoding.GetBytes ("mensagem=" + message);
    stream.Write (bytes, 0, bytes.Length);
}

by the following code:

using (var stream = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8))
{
    var encoded = HttpUtility.UrlEncode("mensagem=" + message)
    stream.Write(encoded);
    stream.Close();
}

You can also try to use other types of Encounter instead of System.Text.Encoding.UTF8, such as the System.Text.Encoding.ASCII

  • I will test, with the 2nd option of invalid request.. still testing..

  • @Dorathoto, strange, in any case I put an additional detail in the answer, I believe it has replaced the wrong excerpt.

  • but I am now testing with Microsoft ASP.NET Web API 2.2 Client seems to be a better solution for what I saw...how to force it into utf-8 ?

  • Error: {"La codifica Nella dichiarazione 'ISO-8859-1' non corrisponde alla codifica del documento 'utf-8'." } My windows is Italian, but da para entender...the error...pq will be?

  • @Dorathoto, as you can see in the source of FormUrlEncodedContent, the same makes use of the HttpRuleParser.DefaultHttpEncoding, which in turn receives the Encounter iso-8859-1... opitionally you can replace the new FormUrlEncodedContent(data) for new StringContent( HttpUtility.UrlEncode("mensagem=" + message), Encoding.UTF8, "application/x-www-form-urlencoded")

  • if you replace the FormUrlEncodedContent for StringContent, will not need to make modifications to Headers of conteudo... you can also use Uri.EscapeDataString("mensagem=" + message).Replace("%20", "+") instead of HttpUtility.UrlEncode("mensagem=" + message)

  • you could kindly include in your reply the end to receive the return after posting, see in my question I just add the end, and I’m not able to use your answer. if possible of course

Show 3 more comments

1


It wouldn’t just be the case escape the Token characters?

var tokenEscapado = Uri.EscapeDataString(token);

HttpUtility.UrlEncode will not work because it is for URL’s, and what is giving problem is a component in the content of the message, which in case is an XML.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.