【问题标题】:how to pass json string and deserialize in WCF如何在 WCF 中传递 json 字符串和反序列化
【发布时间】:2016-04-16 23:58:01
【问题描述】:

我有一个 json 字符串

json1 = "{\"Shops\":[{\"id\":\"1\",\"title\":\"AAA\"},{\"id\":\"2\",\"title\":\"BBB\"}],\"movies\":[{\"id\":\"1\",\"title\":\"Sherlock\"},{\"id\":\"2\",\"title\":\"The Matrix\"}]}";

想要反序列化并获取 requestcollectionclass 中两个类 shop 和 movies 中的值。

 [WebInvoke(
               Method = "POST",
               UriTemplate = "SubmitRequest",
               RequestFormat = WebMessageFormat.Json,
               ResponseFormat = WebMessageFormat.Json
               )
        ]
  string SubmitRequest(string RequestDetailsjson);

在service.cs中

JavaScriptSerializer serializer = new JavaScriptSerializer();
            RequestDetailsCollection requestdetailscoll = serializer.Deserialize<RequestDetailsCollection>(RequestDetailsjson);

遇到错误

服务器在处理请求时遇到错误。异常消息是“反序列化 System.String 类型的对象时出错。应来自命名空间“”的结束元素“根”。从命名空间 ''.' 中找到元素 'request'。有关更多详细信息,请参阅服务器日志。异常堆栈跟踪是:

我把参数类型改成了流

string SubmitRequest(Stream RequestDetailsjson);

并改了代码

StreamReader sr = new StreamReader(RequestDetailsjson);
JavaScriptSerializer serializer = new JavaScriptSerializer();
RequestDetailsCollection requestdetailscoll = (RequestDetailsCollection)serializer.DeserializeObject(sr.ReadToEnd());

然后出现错误

服务器在处理请求时遇到错误。异常消息是“用于操作“SubmitRequest”的传入消息(具有命名空间“http://tempuri.org/”的合同“IService1”)包含无法识别的 http 正文格式值“Json”。预期的正文格式值为“原始”。这可能是因为尚未在绑定上配置 WebContentTypeMapper。有关详细信息,请参阅 WebContentTypeMapper 的文档。有关更多详细信息,请参阅服务器日志。异常堆栈跟踪是:

帮我解决这个问题

【问题讨论】:

  • RequestDetailsCollection的邮政编码

标签: c# json wcf serialization json-deserialization


【解决方案1】:

我也遇到了这个错误,我是这样解决的:

我也想要一个 Stream,当发送 Content-Type: application/json 时它正在中断(如果没有指定内容类型,即 Raw,则可以)。如果对方指定了内容类型,我希望它能够工作。

所以创建此文件RawContentTypeMapper.cs 并将以下内容粘贴到

using System.ServiceModel.Channels;

namespace Site.Api
{

    public class RawContentTypeMapper : WebContentTypeMapper
    {
        public override WebContentFormat GetMessageFormatForContentType(string contentType)
        {
            // this allows us to accept XML (or JSON now) as the contentType but still treat it as Raw
            // Raw means we can accept a Stream and do things with that (rather than build classes to accept instead)
            if (
                contentType.Contains("text/xml") || contentType.Contains("application/xml")
                || contentType.Contains("text/json") || contentType.Contains("application/json")
                )
            {
                return WebContentFormat.Raw;
            }
            return WebContentFormat.Default;
        }
    }
}

在您的 web.config 中,您需要指定要使用的它(&lt;system.serviceModel&gt; 部分中的所有以下内容):

 <bindings>
    <binding name="RawReceiveCapableForHttps">
        <webMessageEncoding webContentTypeMapperType="Site.Api.RawContentTypeMapper, Site, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        <httpsTransport manualAddressing="true" maxReceivedMessageSize="524288000" transferMode="Streamed"/>
    </binding>
</bindings>

您也需要更新您的服务才能使用它:

<services>
    <service behaviorConfiguration="XxxBehaviour" name="Site.Api.XXXX">
        <endpoint address="" behaviorConfiguration="web" binding="customBinding" bindingConfiguration="RawReceiveCapableForHttps" contract="Site.Api.IXXXX" />
    </service>
</services>

为了完整起见,这也是我的行为部分

<behaviors>
  <serviceBehaviors>
    <behavior name="XxxBehaviour">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="web">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

【讨论】:

    【解决方案2】:

    简短的问题,您想知道如何反序列化您的 json 消息。 这是怎么做的。

     var json1 = "{\"Shops\":[{\"id\":\"1\",\"title\":\"AAA\"},{\"id\":\"2\",\"title\":\"BBB\"}],\"movies\":[{\"id\":\"1\",\"title\":\"Sherlock\"},{\"id\":\"2\",\"title\":\"The Matrix\"}]}";
     var requestDetailsCollection = JsonConvert.DeserializeObject<RequestDetailsCollection>(json1);
    

    你的实体类应该是这样的。 (使用选择性粘贴生成的代码)

    public class RequestDetailsCollection 
    {
        public Shop[] Shops { get; set; }
        public Movie[] movies { get; set; }
    }
    
    public class Shop
    {
        public string id { get; set; }
        public string title { get; set; }
    }
    
    public class Movie
    {
        public string id { get; set; }
        public string title { get; set; }
    }
    

    【讨论】:

    • 使用List&lt;T&gt; 代替数组。
    • @AmitKumarGhosh 这就是 Visual Studio 的工作方式。那何必呢?
    【解决方案3】:

    由于RequestDetailsCollection 没有代码,我使用json2csharp 将您的json 转换为对象:

    public class Shop
    {
        public string id { get; set; }
        public string title { get; set; }
    }
    
    public class Movie
    {
        public string id { get; set; }
        public string title { get; set; }
    }
    
    public class RequestDetailsCollection
    {
        public List<Shop> Shops { get; set; }
        public List<Movie> movies { get; set; }
    }
    


    像这样反序列化:

    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var requestdetailscoll = serializer.Deserialize<RequestDetailsCollection>(jsonString);
    


    返回:

    【讨论】:

    • 你应该看看 OP 关心的类。
    • 感谢您的回复。我已经尝试在控制台应用程序中反序列化获得结果。但是在 WCF 中定义的字符串参数并使用邮递员 REST 客户端传递相同的 jsonstring。并得到我在问题中提到的错误..我想知道是否传递字符串参数或流参数以进行反序列化和示例工作 wcf 代码。我正在尝试将其批量插入到我的数据库中的多个表中
    【解决方案4】:

    感谢您的回复。我在一个班级中有两个不同班级的列表 我想传递json字符串并序列化。

    [WebInvoke(
                   Method = "POST",
                   UriTemplate = "SubmitRequest",
                   RequestFormat = WebMessageFormat.Json,
                   ResponseFormat = WebMessageFormat.Json
                   )
            ]
             string SubmitRequest(string RequestDetailsjson);
    

    在服务代码中 JavaScriptSerializer 序列化器 = new JavaScriptSerializer(); RequestDetailsCollection requestdetailscoll = serializer.Deserialize(RequestDetailsjson);

    在 POSTMAN REST 客户端中出现错误 服务器在处理请求时遇到错误。异常消息是“反序列化 System.String 类型的对象时出错。应来自命名空间“”的结束元素“根”。从命名空间 ''.' 中找到元素 'request'。有关更多详细信息,请参阅服务器日志。异常堆栈跟踪是:

    像这样传递流参数 字符串 SubmitRequest(Stream RequestDetailsjson); 低于错误

    服务器在处理请求时遇到错误。异常消息是“用于操作“SubmitRequest”的传入消息(具有命名空间“http://tempuri.org/”的合同“IService1”)包含无法识别的 http 正文格式值“Json”。预期的正文格式值为“原始”。这可能是因为尚未在绑定上配置 WebContentTypeMapper。有关详细信息,请参阅 WebContentTypeMapper 的文档。有关更多详细信息,请参阅服务器日志。异常堆栈跟踪是:

    【讨论】:

      猜你喜欢
      • 2013-03-01
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      相关资源
      最近更新 更多