C# JsonConvert.DeserializeObject和;d";WCF中的包装器

C# JsonConvert.DeserializeObject和;d";WCF中的包装器,c#,.net,wcf,json,json.net,C#,.net,Wcf,Json,Json.net,默认情况下,WCF服务将JSON响应封装在“d”包装器中,在那里我发现解析它时出现问题 如果我使用JsonConvert.DeserializeObject(response)解析,其中response是 "{\"d\":\"{\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\":\"Thelma\",\"d56d4d4f-6029-40df-a23b-de27617a1e43\":\"Louise\"}\"}" 我遇到了一个错误: After parsing a

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

如果我使用JsonConvert.DeserializeObject(response)解析,其中response是

"{\"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?

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

现在,我用正则表达式去掉了“d”包装。用适当的结构替换并修复JSON响应

{\"Guid\":\"a0b70d2f-7fe4-4aa2-b600-066201eab82d\",\"Name\":\"Thelma\"}
{\"Guid\":\"d56d4d4f-6029-40df-a23b-de27617a1e43\",\"Name\":\"Lousie\"}\"}
我还创建了一个带有Guid和Name的类,在其中定义为string

然后尝试用

List<myStruct> o = JsonConvert.DeserializeObject<List<myStruct>>(response);

诀窍在哪里?

如果您切换到WebHttpBehavior,但仍会收到一条关于未包装正文元素的错误消息,请手动将正在处理的方法的正文样式设置为包装。这样做:

[OperationContract(BodyStyle=WebMessageBodyStyle.Wrapped,…] 字符串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<Vendor> RetrieveMultiple(int start, int limit, string sort, string dir)
          {
             //I don't do any manual serialization
             return new Vendor();
          }
        }
}
名称空间应用程序.Service
{
[ServiceBehavior(UseSynchronizationContext=false,
ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode=InstanceContextMode.PerCall),
AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
公共类供应商服务:IVendorService
{
public List RetrieveMultiple(int start、int limit、字符串排序、字符串dir)
{
//我不做任何手动序列化
返回新供应商();
}
}
}
合同:

    [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);
     }
[ServiceContract(Namespace=“Application.Service.Contracts”)]
公共接口IVendorService
{
[经营合同]
[WebInvoke(ResponseFormat=WebMessageFormat.Json,BodyStyle=WebMessageBodyStyle.WrappedRequest)]
List RetrieveMultiple(int start、int limit、字符串排序、字符串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>


我假设您在行为配置中使用了
,将其替换为
,您将得到漂亮干净的json,没有“d”和“\u type”

将json粘贴到在线类生成器中,如图所示。它将为您提供反序列化此json对象的代码,如下所示(VB示例):


将其粘贴到项目中,并将json反序列化到此对象中。现在,D属性是一个字符串,其中包含您需要再次反序列化到最终接收对象中的未包装json。如果您不确定需要处理的类,请将D中的字符串粘贴到同一个联机类生成器中,您将获得创建接收对象的类型所需的代码

我试图改变这一点,但随后出现了一个错误:契约“组织”的操作“保存”指定了要序列化的多个请求体参数,而不包含任何包装器元素。在没有包装器元素的情况下,最多可以序列化一个主体参数。删除额外的主体参数或将WebGetAttribute/WebInvokeAttribute上的BodyStyle属性设置为Wrapped。我的保存方法如下:[OperationContract]bool Save(string orgGuid、string orgName、string orgCode、string orgAddress、int orgStatus)否则这个“d”包装器是可以的,但为什么它在解析时会产生错误呢?我正在查看示例。好的,如果JSON字符串中只有一条记录,这一切都很好,但是如果你有更多的记录,那么…你也在反序列化什么?我们可以看到mystruct吗?如果删除
,您将无法从jquery中的ajax请求访问该服务
<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>
Public Class MyClass
     Public Property D As String
End Class