2013-07-25 41 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的字節數組,因爲沒有內容覆蓋初始化數組。

相關問題