C#中的HttpWebRequest Content-type未更改

3
在C#中,我需要使用HTTP向Web服务器POST一些数据。我不断收到Web服务器返回的错误消息,并在查看数据后发现问题是Content-type标头仍然设置为"text/html",而没有像我的程序中那样更改为"application/json; Charset=UTF-8"。我已经尝试了所有可能阻止更改的方法,但是现在已经没有想法了。
这里是导致问题的函数:
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 "";
    }

我遇到问题的原因是无论我将其设置为什么,内容类型仍然保持为"text/html"。

提前致谢。


Web服务是否接受JSON格式的数据? - brainless coder
是的。我遇到的唯一问题是内容类型不会改变。 - Ed R
你尝试过使用"application/json"而不是"application/json; charset=UTF-8";吗? - brainless coder
刚试了一下,情况没变。内容类型仍为“text/html”。 - Ed R
好的,我刚刚花了半天时间在这个问题上。显然,在我的端口上调用的顺序很重要。我注意到在设置Web请求的其他属性之后,ContentType属性被重置为null。我将ContentType设置移到GetRequestStream之前的最后一个位置,然后它就起作用了。真是令人惊讶,属性设置的顺序可以改变其他属性的设置。可耻。 - Scott Pavetti
显示剩余3条评论
2个回答

3

听起来很奇怪,但是这对我有用:

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

该代码更改了内部的ContentType,从而更新了继承的属性。
我不确定为什么会起作用,但我猜测与ContentTypeWebRequest中抽象属性有关,在HttpWebRequest中被重写导致出现了一些错误或问题。

2
一个潜在的问题是,您基于字符串长度设置内容长度,但这不一定是要发送的正确长度。换句话说,您实际上有:
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);
}

如果将您的字符串编码为UTF-8后结果超过data.Length个字节,那么这将会导致问题。如果您有非ASCII字符(即带重音符号的字符、来自非英语语言的符号等),就可能会发生这种情况。因此,您的整个字符串将无法发送。
您需要编写以下内容:
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);
}

话虽如此,我不理解你的ContentType属性为什么没有被正确设置。我从未见过这种情况发生。


1
更改后问题似乎已经解决了 - 不知道为什么。我使用了 Encoding.UTF-8.GetByteCount(data) 来获取字节数,而不是创建另一个变量。 - Ed R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接