【问题标题】:Serializing JSON string to Match WCF Service Function Parameter序列化 JSON 字符串以匹配 WCF 服务函数参数
【发布时间】:2011-12-12 14:37:21
【问题描述】:

我在序列化 JSON 中的对象以匹配 WCF 函数调用的参数名称时遇到问题。问题是映射参数名称,即传入的 JSON 字符串的起始值应与函数中传递的参数名称相同,例如

"{\"GetComplexDataResult\":{\"BoolValue\":true,\"StringValue\":\"Hello World!\"}}"

这是我在客户端调用的 WCF 函数,您可以看到参数名称与返回的“GetComplexDataResult”相同

[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
String SaveData(CompositeType GetComplexDataResult);

出现的问题是当我尝试使用 Microsoft System.Web.Script.Serialization.JavaScriptSerializer 或任何其他库(例如 Json.NET)序列化我的对象时

即使我传递同一类“CompositeType”的对象(这是客户端代码),它也只会返回我{\"BoolValue\":true,\"StringValue\":\"Hello World!\"},例如

CompositeType GetComplexDataResult= new CompositeType();
GetComplexDataResult.BoolValue = true;
GetComplexDataResult.StringValue = "Hello World";

JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(patchVersion);

我的问题是如何获取这个 JSON 字符串

"{\"GetComplexDataResult\":{\"BoolValue\":true,\"StringValue\":\"Hello World!\"}}"

代替

{\"BoolValue\":true,\"StringValue\":\"Hello World!\"}

只需将我的对象传递给 JSON 解析器。我可以在生成我的 JSON 字符串后手动连接它,但这会耗费太多时间。有没有可以解决这个问题的解析器。

【问题讨论】:

    标签: c# wcf json rest


    【解决方案1】:

    如果您使用参数名称作为属性名称来序列化匿名对象,它将包含在 json 字符串中。试试这个:

    string json = serializer.Serialize(new { GetComplexDataResult = patchVersion});
    

    另外,如果您根本不关心参数名称是否包含在 JSON 中,您可以将 BodyStyle 设置为 BodyStyle = WebMessageBodyStyle.Bare

    【讨论】:

      【解决方案2】:

      我的问题是,您是否需要在 json 数据的开头使用 \"GetComplexDataResult\"

      我不相信 json 序列化程序会按照您的意愿进行本机操作,您几乎必须自己处理。

      在我工作的公司中,我们所做的是构建自己的响应包装器,使我们所有的响应对于我们所有的 json 服务都具有相同的格式。因此,我们几乎制作了一个标准数据合约,它为外部包装器的一个属性返回一个数据合约。您可以执行类似的操作来获得您正在寻找的“嵌套”功能。

      这是一个例子:

      [DataContract]
          public class ServiceResult<T>
          {
              [DataMember]
              public T GetComplexDataResult{ get; set; }
          }
      

      更新:将其修改为通用。想进一步解释我的原始答案要去哪里。再次漂流的答案更简洁,请记住,如果你想扩展,比如添加消息,你必须做这样的事情,或者自己手动做。我真的很喜欢这种方法,因为我知道无论我调用哪个 WCF 服务,我的格式总是相同的。

      【讨论】:

      • 是的,因为 WCF 将 JSON 字符串中的名称映射到传递给函数的参数,例如String SaveData(CompositeType GetComplexDataResult) 有一个名为“GetComplexDataResult”的参数,要将值映射到此对象,JSON 字符串应为“{\"GetComplexDataResult\":{\"BoolValue\":true,\"StringValue\":\"你好世界!\”}}”。我需要看看在我的对象周围创建一个包装器对我有多大帮助。
      • 正如我所指出的,我会按照您的要求做同样的事情,但是我们将它包装在一个通用的外部 ServiceResult 合同中,其中内部属性是 public T[] Data { get;放; }。所以返回的数据总是在返回的“Data”json中。 adrift 的答案本质上是做同样的事情,你会得到同样的结果。
      【解决方案3】:

      对于我见过的每个 JSON 解析器 - 对象类型从未包含在 JSON 中。序列化表示该对象的一个​​实例。如果您需要知道对象源类型引用,最好添加type 属性。 {\"BoolValue\":true,\"StringValue\":\"Hello World!\",\"type\":\"GetComplexDataResult\"}

      你的输出让我想起了一个 SOAP 信封。你不需要封装——它只会让它变得更复杂。 JSON 很简单 - 保持简单。

      【讨论】:

      • 这里的问题不在于类型,而在于在生成的 JSON 的开头添加对象名称“GetComplexDataResult”。 WCF 映射来自 JSON 字符串的名称和您传递给函数的参数。 WCF json 响应是这样的, "{\"GetComplexDataResult\":{\"BoolValue\":true,\"StringValue\":\"Hello World!\"}}" 并且我正在使用 GET 调用函数自动将函数名称“GetComplexData”和额外的“Result”属性附加到它。所以,我在想,像 WCF 所做的那样,可能有办法解决这个问题,所以它一定是可能的。
      猜你喜欢
      • 2018-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多