Ed R
Ed R

Reputation: 91

C# HttpWebRequest Content-type not Changing

In C# i need to POST some data to a web server using HTTP. I keep getting errors returned by the web server and after sniffing throught the data I dound that the problem is that thew Content-type header is still set to "text/html" and isn't getting changed to "application/json; Charset=UTF-8" as in my program. I've tried everything I can think of that might stop it getting changed, but am out of ideas.

Here is the function that is causing problems:

private string post(string uri, Dictionary<string, dynamic> parameters)
    {
        //Put parameters into long JSON string
        string data = "{";
        foreach (KeyValuePair<string, dynamic> item in parameters)
        {
            if (item.Value.GetType() == typeof(string))
            {
                data += "\r\n" + item.Key + ": " + "\"" + item.Value + "\"" + ",";
            }
            else if (item.Value.GetType() == typeof(int))
            {
                data += "\r\n" + item.Key + ": " + item.Value + ",";
            }
        }
        data = data.TrimEnd(',');
        data += "\r\n}";

        //Setup web request
        HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(Url + uri);
        wr.KeepAlive = true;
        wr.ContentType = "application/json; charset=UTF-8";
        wr.Method = "POST";
        wr.ContentLength = data.Length;
        //Ignore false certificates for testing/sniffing
        wr.ServerCertificateValidationCallback = delegate { return true; };
        try
        {
            using (Stream dataStream = wr.GetRequestStream())
            {
                //Send request to server
                dataStream.Write(Encoding.UTF8.GetBytes(data), 0, data.Length);
            }
            //Get response from server
            WebResponse response = wr.GetResponse();
            response.Close();
        }
        catch (WebException e)
        {
            MessageBox.Show(e.Message);
        }
        return "";
    }

The reason i'm getting problems is because the content-type stays as "text/html" regardless of what I set it as.

Thanks in advence.

Upvotes: 3

Views: 7237

Answers (2)

Barnstokkr
Barnstokkr

Reputation: 3129

As odd as this might sound, but this worked for me:

((WebRequest)httpWebRequest).ContentType =  "application/json";

this changes the internal ContentType which updates the inherited one.

I am not sure why this works but I would guess it has something to do with the ContentType being an abstract property in WebRequest and there is some bug or issue in the overridden one in HttpWebRequest

Upvotes: 3

Jim Mischel
Jim Mischel

Reputation: 134045

A potential problem is that you're setting the content length based on the length of the string, but that's not necessarily the correct length to send. That is, you have in essence:

string data = "whatever goes here."
request.ContentLength = data.Length;
using (var s = request.GetRequestStream())
{
    byte[] byteData = Encoding.UTF8.GetBytes(data);
    s.Write(byteData, 0, data.Length);
}

This is going to cause a problem if encoding your string to UTF-8 results in more than data.Length bytes. That can happen if you have non-ASCII characters (i.e. accented characters, symbols from non-English languages, etc.). So what happens is your entire string isn't sent.

You need to write:

string data = "whatever goes here."
byte[] byteData = Encoding.UTF8.GetBytes(data);
request.ContentLength = byteData.Length;  // this is the number of bytes you want to send
using (var s = request.GetRequestStream())
{
    s.Write(byteData, 0, byteData.Length);
}

That said, I don't understand why your ContentType property isn't being set correctly. I can't say that I've ever seen that happen.

Upvotes: 2

Related Questions