默认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?
答案 0 :(得分:11)
我假设您在行为配置中使用<enableWebScript/>
,将其替换为<webHttp defaultOutgoingResponseFormat="Json"/>
,您将得到漂亮而干净的json,没有“d”且没有“__type”
答案 1 :(得分:2)
看起来您正在使用webHttpBinding上的enableWebScript行为。您可能应该使用webHttp行为 - 这为您提供了“干净”的JSON而不是ASP.NET AJAX客户端JSON。
答案 2 :(得分:1)
把你的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中的字符串粘贴到同一个在线类生成器中,并且您将拥有创建接收对象类型所需的代码!
答案 3 :(得分:0)
现在我摆脱了使用Regex.Replace的“d”包装并修复了具有适当结构的JSON响应
{\"Guid\":\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\",\"Name\":\"Thelma\"}
{\"Guid\":\"d56d4d4f-6029-40df-a23b-de27617a1e43\",\"Name\":\"Lousie\"}\"}
我还创建了一个带有Guid和Name的类,在其中定义为字符串。
然后尝试使用
反序列化它List<myStruct> o = JsonConvert.DeserializeObject<List<myStruct>>(response);
但是我收到了错误
Expected a JsonObjectContract or JsonDictionaryContract for type 'System.Collections.Generic.List`1[mynamespace.myStruct]', got 'Newtonsoft.Json.Serialization.JsonArrayContract'.
诀窍在哪里?
答案 4 :(得分:0)
如果您要切换到WebHttpBehavior并且仍然收到有关未被包裹的正文元素的错误消息,请手动将您正在处理的方法的正文样式设置为Wrapped。这样做:
[OperationContract(BodyStyle = WebMessageBodyStyle.Wrapped,...)] 字符串DoSomething(...)
希望这有帮助!
答案 5 :(得分:0)
你可以有一个反序列化包装类,它有一个名为“d”的属性。一旦成功反序列化,然后从d属性中获取值。
答案 6 :(得分:0)
也许这有帮助。
服务:
namespace Application.Service
{
[ServiceBehavior(UseSynchronizationContext = false,
ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall),
AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class VendorService : IVendorService
{
public List<Vendor> 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<Vendor> RetrieveMultiple(int start, int limit, string sort, string dir);
}
我的Svc文件只有这一行:
<%@ ServiceHost Service="Application.Service.VendorService" %>
的Web.config
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript />
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<service behaviorConfiguration="DefaultServiceBehavior" name="Application.Service.VendorService">
<endpoint behaviorConfiguration="jsonBehavior" address="" binding="webHttpBinding" contract="Application.Service.Contracts.IVendor" />
</service>