Wson中的JsonConvert.DeserializeObject和“d”包装器

默认情况下,WCF服务在“d”包装器中包装JSON响应,在那里我发现解析它有问题。

如果我用JsonConvert.DeserializeObject(响应)解析响应

"{\"d\":\"{\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\":\"Thelma\",\"d56d4d4f-6029-40df-a23b-de27617a1e43\":\"Louise\"}\"}" 

我错了:

 After parsing a value an unexpected character was encoutered: a. Line 1, position 9. 

如果我改变响应

 "{\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\":\"Thelma\",\"d56d4d4f-6029-40df-a23b-de27617a1e43\":\"Louise\"}" 

我搞定了。

那么如何从WCF服务解析这个“d”包装的JSON响应呢? 有没有更好的方法来解析JSON?

我假设你在你的行为配置中使用 ,用替换它,你会得到漂亮和干净的json,没有“d”而没有“__type”

看起来您正在使用webHttpBinding上的enableWebScript行为。 您可能应该使用webHttp行为 – 这为您提供了“干净”的JSON而不是ASP.NET AJAX客户端JSON。

把你的json粘贴到一个在线类生成器中,比如http://httputility.net/json-to-csharp-vb-typescript-class.aspx 。 它将为您提供将此json对象反序列化的代码,如下所示(VB示例):

 Public Class MyClass Public Property D As String End Class 

将其粘贴到项目中,并将json反序列化为此对象。 D属性现在是一个字符串,其中包含您需要将第二次反序列化到最终接收对象中的展开的json。 如果您不确定要处理它的类,请将D中的字符串粘贴到同一个在线类生成器中,您将拥有创建接收对象类型所需的代码!

现在我摆脱了使用Regex.Replace的“d”包装并修复了具有适当结构的JSON响应

 {\"Guid\":\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\",\"Name\":\"Thelma\"} {\"Guid\":\"d56d4d4f-6029-40df-a23b-de27617a1e43\",\"Name\":\"Lousie\"}\"} 

我还创建了一个带有Guid和Name的类,在其中定义为字符串。

然后尝试用它反序列化它

 List o = JsonConvert.DeserializeObject>(response); 

但我得到一个错误

 Expected a JsonObjectContract or JsonDictionaryContract for type 'System.Collections.Generic.List`1[mynamespace.myStruct]', got 'Newtonsoft.Json.Serialization.JsonArrayContract'. 

诀窍在哪里?

如果要切换到WebHttpBehavior并且仍然收到有关未包装的body元素的错误消息,请手动将您正在处理的方法的正文样式设置为Wrapped。 这样做:

[OperationContract(BodyStyle = WebMessageBodyStyle.Wrapped,…)] string DoSomething(…)

希望这可以帮助!

你可以有一个反序列化包装类,它有一个名为“d”的属性。 一旦成功反序列化,然后从d属性中获取值。

也许这有帮助。

服务:

 namespace Application.Service { [ServiceBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall), AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class VendorService : IVendorService { public List RetrieveMultiple(int start, int limit, string sort, string dir) { //I don't do any manual serialization return new Vendor(); } } } 

合约:

  [ServiceContract(Namespace = "Application.Service.Contracts")] public interface IVendorService { [OperationContract] [WebInvoke(ResponseFormat=WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] List RetrieveMultiple(int start, int limit, string sort, string dir); } 

我的Svc文件只有这一行:

 <%@ ServiceHost Service="Application.Service.VendorService" %> 

Web.config文件