为什么IE6将NULL字符(0x00)作为JSON POST数据发送给我?

时间:2013-07-25 22:05:17

标签: json internet-explorer http jquery

在尝试反序列化从jQuery.ajax()发送的JSON数据时,我的(C#)服务器代码偶尔会出现异常。 POST数据完全是NULL字符(二进制,0x00)。我记录了日志和文本模式中的错误的所有POST数据,它看起来像空格:

"          "

但在二进制模式下,它是:

00 00 00 00 00 00 00 00 00 00

这个完全相同的错误已被记录3次,来自同一个用户,大约相隔15分钟。

可能发生什么事?我用谷歌搜索,发现没有这样的东西。

以下是JSON反序列化程序的实际错误:

System.ArgumentException:  Invalid JSON primitive: .
    at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
    at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
    at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
    at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)

用户代理:

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MS-RTC LM 8; InfoPath.2)

内容类型:

application/json

另一个线索:在我们的全局错误处理程序中,我们尝试向用户写一条响应消息(例如“抱歉,您遇到了问题,我们正在研究它。”)。当我们尝试为此用户执行此操作时,每次我们都遇到同样的异常时:

System.Web.HttpException (0x80070057): The remote host closed the connection. The error code is 0x80070057.
    at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
    at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
    at System.Web.HttpResponse.Flush(Boolean finalFlush)
    at System.Web.HttpResponse.End()

以下是我们阅读数据的方式(我必须复制/粘贴一些库代码):

[Ajax]
[AsyncTimeout(300001)] // 5 minutes
[ValidateInput(false)] // We want to pass in XML via POST
public void CommandAsync()
{
    AsyncManager.OutstandingOperations.Increment();

    // Reads the main body of a request, without closing the
    // stream.  The advantage of not closing the stream is that it can
    // be re-read later, particularly by the Global.asax.cs error
    // handler.
    // It seems that if the content type is not form-url-encoded
    // then the input stream needs to be reset.  Weird.
    Request.InputStream.Position = 0;
    byte[] content = new byte[Request.ContentLength];
    Request.InputStream.Read(content, 0, Request.ContentLength);
    string dataStr = Encoding.UTF8.GetString(content);

    if (dataStr.Length != 0) {
        var data = serializer.Deserialize<Dictionary<string, object>>(dataStr);

        // do something with data
    }
}

[编辑]

Eric是正确的,因为IE在流中没有发送任何数据。

因此我们的解决方案是将数组缩小到读取的内容:

    int content_length = request.ContentLength;
    byte[] content = new byte[content_length];
    int read = request.InputStream.Read(content, 0, content_length);
    if (read < content_length)
        Array.Resize(ref content, read);

或者,我们可以简单地使用StreamReader(request.InputStream).ReadToEnd(),效率会低一些,但是从来没有遇到过这个bug。

1 个答案:

答案 0 :(得分:1)

谢谢Eric,你是对的!

当在Internet Explorer中取消AJAX帖子请求时,它仍然将它们发送到服务器,但没有实际内容且标题中的内容长度不正确。

我们使用以下内容阅读内容:

request.InputStream.Position = 0;
byte[] content = new byte[request.ContentLength];
request.InputStream.Read(content, 0, request.ContentLength);

它创建了一个\ 0的字节数组,因为没有内容可以覆盖初始化的数组。