如何在WCF中传递json字符串并反序列化

use*_*508 3 c# wcf serialization json json-deserialization

我有一个 json 字符串

json1 = "{\"Shops\":[{\"id\":\"1\",\"title\":\"AAA\"},{\"id\":\"2\",\"title\":\"BBB\"}],\"movies\":[{\"id\":\"1\",\"title\":\"Sherlock\"},{\"id\":\"2\",\"title\":\"The Matrix\"}]}";
Run Code Online (Sandbox Code Playgroud)

想要反序列化并获取 requestcollection 类中的两个类商店和电影中的值。

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

并在service.cs中

JavaScriptSerializer serializer = new JavaScriptSerializer();
            RequestDetailsCollection requestdetailscoll = serializer.Deserialize<RequestDetailsCollection>(RequestDetailsjson);
Run Code Online (Sandbox Code Playgroud)

出现错误

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

我将参数类型更改为stream

string SubmitRequest(Stream RequestDetailsjson);
Run Code Online (Sandbox Code Playgroud)

并更改了代码

StreamReader sr = new StreamReader(RequestDetailsjson);
JavaScriptSerializer serializer = new JavaScriptSerializer();
RequestDetailsCollection requestdetailscoll = (RequestDetailsCollection)serializer.DeserializeObject(sr.ReadToEnd());
Run Code Online (Sandbox Code Playgroud)

并出现错误

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

帮我解决这个问题

Mat*_*emp 6

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

我也想要一个 Stream,当Content-Type: application/json发送 a 时它就中断了(如果没有指定内容类型,即原始数据,那就可以了)。我希望无论对方是否指定内容类型,它都能工作。

因此,创建此文件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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的 web.config 中,您需要指定要使用的它(本<system.serviceModel>节中的所有以下内容):

 <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>
Run Code Online (Sandbox Code Playgroud)

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

<services>
    <service behaviorConfiguration="XxxBehaviour" name="Site.Api.XXXX">
        <endpoint address="" behaviorConfiguration="web" binding="customBinding" bindingConfiguration="RawReceiveCapableForHttps" contract="Site.Api.IXXXX" />
    </service>
</services>
Run Code Online (Sandbox Code Playgroud)

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

<behaviors>
  <serviceBehaviors>
    <behavior name="XxxBehaviour">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="web">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>
Run Code Online (Sandbox Code Playgroud)