简体   繁体   中英

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.

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

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 (ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM