Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用单一OperationContract方法支持WCF XML和JSON?_Wcf - Fatal编程技术网

使用单一OperationContract方法支持WCF XML和JSON?

使用单一OperationContract方法支持WCF XML和JSON?,wcf,Wcf,我花了好几天的时间努力满足以下要求。我希望我的WCFAPI使用单个方法处理XML和JSON请求/响应。我还知道.NET4支持自动格式选择,但它的工作方式与我希望的XML和JSON结构不同。以下是我的结构: JSON: XML: 以下是数据合同: [DataContract] public class Test: ITest { responsePushNotify = new ResponsePushNotify(); ResponsePushNotify

我花了好几天的时间努力满足以下要求。我希望我的WCFAPI使用单个方法处理XML和JSON请求/响应。我还知道.NET4支持自动格式选择,但它的工作方式与我希望的XML和JSON结构不同。以下是我的结构:

JSON:

XML:

以下是数据合同:

 [DataContract]
    public class Test: ITest
    {
    responsePushNotify = new ResponsePushNotify();
       ResponsePushNotify PushNotify(RequestPushNotifiy pushnotify)
    {
        if (Content-Type == "application/json; charset=utf-8")  
            {  
                OperationContext.Current.OutgoingMessageProperties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));  
            }  
    responsePushNotify.id = "1";
    responsePushNotify.value = "Hello World";

    return responsePushNotify ;
    }
以下是建议的代码:

public class MyWebHttpBehavior : WebHttpBehavior
    {
        protected override IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
        {
            WebGetAttribute webGet = operationDescription.Behaviors.Find<WebGetAttribute>();
            IDispatchMessageFormatter json = null, xml = null;
            WebMessageFormat originalFormat = webGet.ResponseFormat;
            webGet.ResponseFormat = WebMessageFormat.Json;
            json = base.GetReplyDispatchFormatter(operationDescription, endpoint);
            webGet.ResponseFormat = WebMessageFormat.Xml;
            xml = base.GetReplyDispatchFormatter(operationDescription, endpoint);
            webGet.ResponseFormat = originalFormat;
            return new MyReplyDispatchMessageFormatter(json, xml);
        }
    }
    public class MyReplyDispatchMessageFormatter : IDispatchMessageFormatter
    {
        IDispatchMessageFormatter jsonFormatter;
        IDispatchMessageFormatter xmlFormatter;
        public MyReplyDispatchMessageFormatter(IDispatchMessageFormatter jsonFormatter, IDispatchMessageFormatter xmlFormatter)
        {
            this.jsonFormatter = jsonFormatter;
            this.xmlFormatter = xmlFormatter;
        }
        public void DeserializeRequest(Message message, object[] parameters)
        {
            throw new NotSupportedException("Used for replies only");
        }

        public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
            IDispatchMessageFormatter formatter = this.xmlFormatter;
            if (OperationContext.Current.OutgoingMessageProperties.ContainsKey(WebBodyFormatMessageProperty.Name))
            {
                WebBodyFormatMessageProperty webBody = (WebBodyFormatMessageProperty)OperationContext.Current.OutgoingMessageProperties[WebBodyFormatMessageProperty.Name];
                if (webBody != null && webBody.Format == WebContentFormat.Json)
                {
                    formatter = this.jsonFormatter;
                }
            }

            return formatter.SerializeReply(messageVersion, parameters, result);
        }
    }
这是我的网络配置:

<?xml version="1.0"?>
<configuration> 
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <services>
      <service behaviorConfiguration="CustomBehavior" name="Service.Test">
        <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="Services.ITest" bindingConfiguration="general"/>
      </service>      
    </services>  
    <bindings>
      <webHttpBinding>
        <binding name="general" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00"
                 receiveTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="4194304"
                 maxBufferSize="2147483647"  />
      </webHttpBinding>
    </bindings>     
    <behaviors>      
      <endpointBehaviors>
        <behavior name="web">
          <webHttp automaticFormatSelectionEnabled="true" />
        </behavior>         
      </endpointBehaviors>
      <serviceBehaviors>       
        <behavior name="CustomBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>       
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel> 
</configuration>

现在我的问题是,如何在代码中定义自定义行为并将其添加到webconfig?我需要做哪些更改?另外,如果我要设置BodyStyle=WebMessageBodyStyle.Wrapped,我该怎么做?在哪里做?

我看到这个问题很久以前就发布了,但可能对某些人有用。我在overcoder.net上找到了解决方案。您只需为所需的输出格式生成相应的字符串,并为结果类型使用流

[OperationContract]
[WebGet(UriTemplate = "test?format={format}")]
System.IO.Stream test(string format);

您可能需要编写自己的customdispatcher。参考下面的链接:太棒了,拉杰什:但是我需要设置WebMessageBodyStyle.Wrapped。拉杰什:我已经完成了你在帖子中提到的工作,并添加了如下完全相同的类:公共类MyWebHttpBehavior:WebHttpBehavior公共类MyReplyDispatchMessageFormatter:IDispatchMessageFormatter公共无效反序列化请求消息,object[]参数public Message SerializeReplyMessageVersion messageVersion,object[]参数,object resultSorry这不允许我一次发布所有代码。下面是我的操作合同:[OperationContract][WebInvokeMethod=POST,UriTemplate=Push]响应PushRequest pushnotifi;这是我的数据约定:Response PushRequest pushnotifi{if requestHeader.ContentType==application/json;charset=utf-8{OperationContext.Current.OutgoingMessageProperties.AddWebBodyFormatMessageProperty.Name,new WebBodyFormatMessageProperty yWebContentFormat.json;}返回响应;}@carlosfigueira:我不允许在这里发布代码,因为它太长,而且非常令人沮丧,除非我回答我自己的问题。有什么办法可以联系你吗?电子邮件什么的?因为这里有很多东西要放,而且我是新来的。
public class MyWebHttpBehavior : WebHttpBehavior
    {
        protected override IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
        {
            WebGetAttribute webGet = operationDescription.Behaviors.Find<WebGetAttribute>();
            IDispatchMessageFormatter json = null, xml = null;
            WebMessageFormat originalFormat = webGet.ResponseFormat;
            webGet.ResponseFormat = WebMessageFormat.Json;
            json = base.GetReplyDispatchFormatter(operationDescription, endpoint);
            webGet.ResponseFormat = WebMessageFormat.Xml;
            xml = base.GetReplyDispatchFormatter(operationDescription, endpoint);
            webGet.ResponseFormat = originalFormat;
            return new MyReplyDispatchMessageFormatter(json, xml);
        }
    }
    public class MyReplyDispatchMessageFormatter : IDispatchMessageFormatter
    {
        IDispatchMessageFormatter jsonFormatter;
        IDispatchMessageFormatter xmlFormatter;
        public MyReplyDispatchMessageFormatter(IDispatchMessageFormatter jsonFormatter, IDispatchMessageFormatter xmlFormatter)
        {
            this.jsonFormatter = jsonFormatter;
            this.xmlFormatter = xmlFormatter;
        }
        public void DeserializeRequest(Message message, object[] parameters)
        {
            throw new NotSupportedException("Used for replies only");
        }

        public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
            IDispatchMessageFormatter formatter = this.xmlFormatter;
            if (OperationContext.Current.OutgoingMessageProperties.ContainsKey(WebBodyFormatMessageProperty.Name))
            {
                WebBodyFormatMessageProperty webBody = (WebBodyFormatMessageProperty)OperationContext.Current.OutgoingMessageProperties[WebBodyFormatMessageProperty.Name];
                if (webBody != null && webBody.Format == WebContentFormat.Json)
                {
                    formatter = this.jsonFormatter;
                }
            }

            return formatter.SerializeReply(messageVersion, parameters, result);
        }
    }
<?xml version="1.0"?>
<configuration> 
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <services>
      <service behaviorConfiguration="CustomBehavior" name="Service.Test">
        <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="Services.ITest" bindingConfiguration="general"/>
      </service>      
    </services>  
    <bindings>
      <webHttpBinding>
        <binding name="general" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00"
                 receiveTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="4194304"
                 maxBufferSize="2147483647"  />
      </webHttpBinding>
    </bindings>     
    <behaviors>      
      <endpointBehaviors>
        <behavior name="web">
          <webHttp automaticFormatSelectionEnabled="true" />
        </behavior>         
      </endpointBehaviors>
      <serviceBehaviors>       
        <behavior name="CustomBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>       
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel> 
</configuration>
[OperationContract]
[WebGet(UriTemplate = "test?format={format}")]
System.IO.Stream test(string format);
public System.IO.Stream test(string format)
{
     ArrayList ar = new ArrayList() { 1, 2, 3 };
     if (format == "text")
         result = String.Join(",", ar.ToArray());
     if (format == "xml")
     { 
        result = @"<soapenv:Envelope>
   <soapenv:Header/>
   <soapenv:Body>
      <result>";
        foreach (int i in ar)
            result += String.Format("\r\n        <item>{0}</item>", i);
        result += @"
      </result>
   </soapenv:Body>
</soapenv:Envelope>";
     }
     if (format == "json")
         result = JsonConvert.SerializeObject(ar, Newtonsoft.Json.Formatting.Indented);

     OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
     context.ContentType = "text/plain";
     return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes(result));
}