来自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)
答案 0 :(得分:2)
我建议关注
public CSharpRequestMappedObject() { Items= New List<SomeClass>(); }
这些是一些通用指南,请发布您的json输入,以便我可以推荐一些更精确的提示。
答案 1 :(得分:1)
我们结束时发现异常实际上是由另一个异常抛出后的瞬间引起的:HttpException:请求超时。 我总是发生大约5/100秒。
因此,原因是Android设备连接不良,这种情况很少发生。
答案 2 :(得分: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设备使用协议相对URL 发出PATCH请求(包含实体主体)时,会发生异常。 如果更改网址以包含协议,则问题就会消失。
我已经使用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&#aajax()方法完成的。
我没有找到如何更好地捕获错误(或者防止它在服务器上发生,可能通过执行一些预处理)的答案,但我认为了解传入的类型会有所帮助请求导致它。