2013-10-23 42 views
1

來自Android設備的一些要求,使我們的服務servicestack.net失敗與此異常:Servicestack SerializationException:無法反序列化「應用/ JSON的」

System.Runtime.Serialization.SerializationException: Could not deserialize 'application/json' request using CSharpRequestMappedObject' 
Error: System.Threading.ThreadAbortException: Thread was being aborted. 
    at System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest(IntPtr pHandler, Byte[] pBuffer, Int32 offset, Int32 cbBuffer, Int32& pBytesRead) 
    at System.Web.Hosting.IIS7WorkerRequest.ReadEntityCoreSync(Byte[] buffer, Int32 offset, Int32 size) 
    at System.Web.HttpRequest.GetEntireRawContent() 
    at System.Web.HttpRequest.get_InputStream() 
    at ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.CreateContentTypeRequest(IHttpRequest httpReq, Type requestType, String contentType) 
    at ServiceStack.WebHost.Endpoints.Support.EndpointHandlerBase.CreateContentTypeRequest(IHttpRequest httpReq, Type requestType, String contentType) 
    at ServiceStack.WebHost.Endpoints.RestHandler.GetRequest(IHttpRequest httpReq, IRestPath restPath) 
    at ServiceStack.WebHost.Endpoints.RestHandler.ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, String operationName) 

我知道它有somethink做的Post'ed JSON數據不能被分析到CSharpRequestMappedObject。

這樣映射:

[Route("/RequestPath/", Verbs = "POST"), UsedImplicitly] 
public class CSharpRequestMappedObject 
{ 
    public string Name{ get; set; } 
    public IList<SomeClass> Items{ get; set; } 
    public bool State { get; set; } 
    public string SpecialType { get; set; } //Not required 
} 

我的問題是我怎麼弄清楚什麼是錯的要求嗎?
它只是有時會發生 - 我看到它在我的服務器日誌中,但我無法重現它。

我在Global.asax中嘗試這樣:

public override void Configure(Container container) 
{  
    ServiceExceptionHandler = (request, ex) => 
    { 
     //Enrich exceptions with request body data. 
     var propertyInfo = HttpContext.Current.Request.GetType().GetProperty("EntityBody", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
     var postBody = Encoding.UTF8.GetString((byte[])propertyInfo.GetValue(HttpContext.Current.Request, null)); 

     throw new Exception("Request body: " + postBody, ex); 
    }; 
} 

它增加了對其他異常請求體數據 - 但這種異常沒有逮住那裏。 (我有一個捕獲異常後一些其他日誌 - ELMAH)

回答

1

我們最終發現異常實際上是由另一個異常引起的:HttpException:Request timed out。 我總是發生約5/100秒後者。

因此,原因是Android設備上的連接不良,這很罕見。

2

我建議以下

  • 使用Fiddler跟蹤請求和響應來回
  • 使用jsonlint驗證您的JSON傳遞開始作爲輸入。在請求DTO
  • 添加構造函數創建像public CSharpRequestMappedObject() { Items= New List<SomeClass>(); }

這些都是一些通用準則項目的新對象,請發表您的JSON輸入,這樣我可以推薦一些更精確的提示。

+0

感謝您的回答 - 我們結束瞭解,原因是請求的超時。 –

0

雖然我意識到這個問題是舊的,但問題仍然存在,似乎是由於Android設備發出的PATCH請求發送格式不正確或未終止的實體,而不是IIS或.NET問題。

當.NET應用程序掛起幾個(或許多)秒,並最終作爲的Morten上文描述引發以下錯誤的問題可以看出:

System.Threading.ThreadAbortException: Thread was being aborted. 
    at System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest(IntPtr pHandler, Byte[] pBuffer, Int32 offset, Int32 cbBuffer, Int32& pBytesRead, UInt32 timeout) 
    at System.Web.Hosting.IIS7WorkerRequest.ReadEntityCoreSync(Byte[] buffer, Int32 offset, Int32 size, Int64 timeout) 
    at System.Web.HttpRequest.GetEntireRawContent() 
    at System.Web.HttpRequest.get_InputStream() 

當Android裝置發出PATCH發生異常請求(包含實體正文)使用協議相關URL如果URL更改爲包含協議,則問題消失

我已經用GET,PUT,PATCH,DELETE和OPTIONS動詞測試過了,只發現它和PATCH一起出現。

我還測試了與Windows 7桌面瀏覽器(Chrome 41,IE11和Firefox 36)以及Android 4.4.2上運行iOS 8.2和Chrome 40的設備相同的動態組合,相對URL。

在所有這些動詞/平臺/瀏覽器/協議組合中,我只有在從使用協議相關URL的Android設備發出PATCH請求時拋出錯誤。如果不包含實體主體,則不會發生錯誤。

另外我首先懷疑它可能與交叉來源請求有關。然而,在對上述組合進行測試後,我發現無論請求是跨域還是同一個域名都沒有區別。同樣,實體主體是JSON還是純文本也沒有區別。所有測試都是在2.1.3版本中使用jQuery的.ajax()方法完成的。

我沒有如何更好地捕捉錯誤(或防止它發生在服務器上,也許通過執行一些預處理)的答案,但我認爲這將有助於知道什麼類型的傳入請求導致它。