使用lambda的奇怪的Json转换错误

时间:2016-08-19 23:05:24

标签: c# json lambda

我将一个Json文档发送到Web API,该Web API将转换为一个Addresses数组。如果我发送一个地址,则以下代码可以正常工作,但是如果我发送了两个地址则会导致死亡。有什么想法吗?

输入失败的Web服务如下所示:

[
  "\"TrackingIdTest_2\"",
  "[
  {\"CustomerAddressKey\":\"1\",\"Address\":\"6069 W STUDIO CT\",\"City\":\"LOS ANGELES\",\"State\":\"CA\",\"Zipcode\":\"\"}
  ,{\"CustomerAddressKey\":\"2\",\"Address\":\"1095 6th Ave\",\"City\":\"NEW YORK\",\"State\":\"NY\",\"Zipcode\":\"\"}
  ]"
]  

如果我发送它有效:

[
  "\"TrackingIdTest_2\"",
  "[
  {\"CustomerAddressKey\":\"1\",\"Address\":\"6069 W STUDIO CT\",\"City\":\"LOS ANGELES\",\"State\":\"CA\",\"Zipcode\":\"\"}
  ]"
]  

抛出错误的代码如下:

var addressesInternal = new List<RequestAddressInternal>();
addresses.ToList().ForEach(x =>
{
   addressesInternal.Add(new RequestAddressInternal()
   {
     InternalAddressKey = Guid.NewGuid().ToString(),
     RequestAddress = x
   });
 });

地址的定义如下:

RequestAddress[] addresses
// Defined in a Model class:
public class RequestAddress
{
    public string CustomerAddressKey { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zipcode { get; set; }
}

RequestAddressInternal如下所示:

public class RequestAddressInternal
{
    public string InternalAddressKey { get; set; }
    public RequestAddress RequestAddress { get; set; }
}

我从网络服务回来的错误是:

{
"Message": "An error has occurred.",
"ExceptionMessage": "This document already has a 'DocumentElement' node.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": "   at System.Xml.XmlDocument.IsValidChildType(XmlNodeType type)\r\n   at System.Xml.XmlNode.AppendChild(XmlNode newChild)\r\n   at Newtonsoft.Json.Converters.XmlNodeWrapper.AppendChild(IXmlNode newChild)\r\n   at Newtonsoft.Json.Converters.XmlNodeConverter.CreateElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, String elementName, XmlNamespaceManager manager, String elementPrefix, Dictionary`2 attributeNameValues)\r\n   at Newtonsoft.Json.Converters.XmlNodeConverter.ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, String propertyName, XmlNamespaceManager manager)\r\n   at Newtonsoft.Json.Converters.XmlNodeConverter.DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, String propertyName, IXmlNode currentNode)\r\n   at Newtonsoft.Json.Converters.XmlNodeConverter.DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode)\r\n   at Newtonsoft.Json.Converters.XmlNodeConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\r\n   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\r\n   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)\r\n   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonConverter[] converters)\r\n   at Newtonsoft.Json.JsonConvert.DeserializeXmlNode(String value, String deserializeRootElementName, Boolean writeArrayAttribute)\r\n   at Midas.WebApi.waCarrierServiceabilityLib.CarrierServiceabilityImpl.ProcessBulkImpl(String serviceRequest, String clientId, String clientRequestTrackingId, RequestAddress[] addresses, String clientOwner, String uid, String ipAddress, Boolean includeGeodata) in E:\\Source Code\\GitHub\\waCarrierServiceability\\waCarrierServiceabilityLib\\CarrierServiceabilityImpl.cs:line 222\r\n   at Midas.WebApi.waCarrierServiceabilityLib.CarrierServiceabilityImpl.ProcessBulk(String serviceRequest, JArray requestRaw, String clientId, String clientOwner, String userId, String ipAddress, Boolean includeGeodata) in E:\\Source Code\\GitHub\\waCarrierServiceability\\waCarrierServiceabilityLib\\CarrierServiceabilityImpl.cs:line 134\r\n   at Midas.WebApi.waCarrierServiceability.Controllers.CarrierServiceabilityController.GetCarrierServiceabilityBulk(JArray jsonParamList) in E:\\Source Code\\GitHub\\waCarrierServiceability\\Controllers\\CarrierServiceability.cs:line 120\r\n   at lambda_method(Closure , Object , Object[] )\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

此时我想知道它是否曾经是某种类型的线程问题?我在try catch和catch异常中包装了最后执行的代码,但没有抛出任何异常,它只是从未进入代码中的下一行。

1 个答案:

答案 0 :(得分:0)

不幸的是,我无法给出完整的答案,但看看,可能值得尝试的几件事情:

  1. 看起来Json解析以获取数组addresses的输入字符串可能会失败(因此,当您在代码中进入此阶段时,它不是两个解析了你期待的Json字符串。您可以尝试在调试器中设置此行的断点,并检查addresses等于什么?

  2. 有时候使用LINQ,看到在lambda调用(x => ...)返回之前发生了什么事情可能会很棘手。要解决这个问题,您可以设置一个临时变量:

    var temp = addresses.ToList();
    

    然后,如果在代码中应用以下步骤,则可以使用此值来检查列表temp中第一个元素会发生什么。单步执行调试器可能有助于查看错误的来源?

  3. 再次道歉,这只是一个可能的想法列表,但希望您能够解决您的问题!