3

默认情况下,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?

4

7 回答 7

11

我假设您<enableWebScript/>在行为配置中使用,将其替换为<webHttp defaultOutgoingResponseFormat="Json"/>,您将获得漂亮干净的 json,没有“d”和“__type”

于 2011-06-03T19:06:59.523 回答
2

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

于 2009-10-26T22:51:55.413 回答
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 中的字符串粘贴到同一个在线类生成器中,您将拥有创建接收对象的类型所需的代码!

于 2015-04-22T17:15:49.507 回答
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'.

诀窍在哪里?

于 2009-10-27T08:32:34.470 回答
0

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

[OperationContract(BodyStyle = WebMessageBodyStyle.Wrapped, ...)] 字符串 DoSomething(...)

希望这可以帮助!

于 2011-03-07T00:47:12.037 回答
0

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

于 2011-03-07T03:39:07.010 回答
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" %>

网页配置

<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>
于 2011-03-09T06:57:22.673 回答