【问题标题】:Servicestack SerializationException: Could not deserialize 'application/json'Servicestack SerializationException:无法反序列化“应用程序/json”
【发布时间】:2015-03-19 14:09:21
【问题描述】:

来自 Android 设备的一些请求使我们的 servicestack.net 服务失败并出现以下异常:

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)

我知道它与 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)

【问题讨论】:

    标签: c# android json servicestack deserialization


    【解决方案1】:

    我会推荐关注

    • 开始使用 Fiddler 来跟踪请求和响应
    • 使用 jsonlint 验证您的 json 作为输入传递。
    • 在请求 DTO 中添加构造函数,用于创建项目的新对象,例如 public CSharpRequestMappedObject() { Items= New List&lt;SomeClass&gt;(); }

    这些是一些通用指南,请发布您的 json 输入,以便我推荐一些更精确的提示。

    【讨论】:

    • 感谢您的回答 - 我们最终确定原因是请求超时。
    【解决方案2】:

    我们最终发现该异常实际上是由另一个异常引发不久之后引发的:HttpException: Request timed out。 我总是在大约 5/100 秒后出现。

    因此,原因是 Android 设备上的连接不良,这是有道理的,因为这种情况很少发生。

    【讨论】:

      【解决方案3】:

      虽然我意识到这个问题已经过时,但问题仍然存在,并且似乎是由于来自 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 设备使用协议相对 URL 发出 PATCH 请求(包含实体主体)时会发生异常。 如果 URL 更改为包含协议,问题就会消失

      我用 GET、PUT、PATCH、DELETE 和 OPTIONS 动词对此进行了测试,发现它只出现在 PATCH 中。

      我还使用 Windows 7 桌面浏览器(Chrome 41、IE11 和 Firefox 36)以及在 Android 4.4.2 上运行 iOS 8.2 和 Chrome 40 的设备测试了相同的动词组合,均具有协议限定和协议相关网址。

      在所有这些动词/平台/浏览器/协议组合中,我只有在使用协议相关 URL 从 Android 设备发出 PATCH 请求时抛出错误。如果不包含实体主体,则不会发生错误。

      此外,我首先怀疑它可能与跨域请求有关。但是,在测试了上述组合之后,我发现请求是跨域还是同域没有区别。同样,实体主体是 JSON 还是纯文本也没有区别。所有测试均使用 jQuery 2.1.3 版本中的 .ajax() 方法完成。

      对于如何更好地捕获错误(或防止错误发生在服务器上,可能通过执行一些预处理),我没有答案,但我认为了解传入请求的类型会有所帮助它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-26
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多