2013-07-25 39 views
0

当试图反序列化从jQuery.ajax()发送的JSON数据时,我在我的(C#)服务器代码中偶尔出现异常。 POST数据完全是NULL字符(二进制,0x00)。我记录在我的日志,并在文本模式错误的所有POST数据,它看起来像位:为什么IE6发送NULL字符(0x00)作为JSON 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(),它会一直效率稍差一点,但从来没有这个错误。

+1

你是如何获取数据到你的C#?通常这样的错误是通过使用阵列或MemoryStream的还没有被完全填充(例如,由于客户端发送较少的数据比预期的)导致的。 – EricLaw

+0

@EricLaw好点!我已经添加了我的数据阅读代码。 – Yoshi

+0

阅读过我自己的代码,我真的应该使用Request.ContentEncoding而不是UTF8。这可能会导致这个问题吗?我假设旧版浏览器会发送ASCII +扩展的代码页字符,UTF8会将其解码为gobbledygook而不是NULL。 – Yoshi

回答

1

谢谢埃里克,你是对的!

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

我们阅读使用内容:

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

它创造的\ 0的字节数组,因为没有内容覆盖初始化数组。

相关问题