1

目前我们使用 .NET 3.5 和 WSCF.blue 编写合约优先的 WCF SOAP 服务。这允许我们设计使用 Xsd 文件交换的 Xml 文档。

现在 WSDL 2.0 已经存在,您可以为 REST 端点设计契约,并且 .NET 4.5 中首先对契约有适当的支持,我们有以下问题:

是否可以升级到 Visual Studio 2012,保留我们现有的 Xsd 集并自动公开 REST 和/或 SOAP 端点?

是否可以升级到 Visual Studio 2012,保留我们现有的 Xsd 集并自动交换 Xml 和/或 Json 文档?

4

1 回答 1

0

这是我的解决方案:

您至少需要 Visual Studio 2012。

创建一个 WCF 服务库项目。

包含您的 Xsd 文件以自动创建数据协定包装器。

像这样编写您的 ServiceContract 和类:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace RestSoapTest
{
    public class Service1 : IService1
    {
        public List<CompositeType> GetData(string paramA, string paramB)
        {
            List<CompositeType> output = new List<CompositeType>();

            output.Add(new CompositeType()
            {
                Key = paramA,
                Value = paramB,
            });
            output.Add(new CompositeType()
            {
                Key = paramA,
                Value = paramB,
            });
            output.Add(new CompositeType()
            {
                Key = paramA,
                Value = paramB,
            });

            return output;
        }

        public void PutData(string paramA, string paramB, List<CompositeType> data)
        {
            throw new NotImplementedException();
        }
    }

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebGet(UriTemplate = "GetData/{paramA}/{paramB}")]
        List<CompositeType> GetData(string paramA, string paramB);

        [OperationContract]
        [WebInvoke(UriTemplate = "PutData/{paramA}/{paramB}")]
        void PutData(string paramA, string paramB, List<CompositeType> data);
    }

    [DataContract]
    public class CompositeType
    {
        [DataMember]
        public string Key { get; set; }
        [DataMember]
        public string Value { get; set; }
    }
}

(手动编写 DataContract 或使用 Xsd 控制它)

添加一个 Web 宿主项目,引用 WCF 项目并添加这个 web.config 文件:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="standardRest" automaticFormatSelectionEnabled="true" defaultOutgoingResponseFormat="Json" helpEnabled="true"/>
      </webHttpEndpoint>
      <mexEndpoint>
        <standardEndpoint name="standardMex"/>
      </mexEndpoint>
    </standardEndpoints>
    <services>
      <service name="RestSoapTest.Service1">
        <endpoint name="rest" address="" kind="webHttpEndpoint" endpointConfiguration="standardRest" contract="RestSoapTest.IService1"/>
        <endpoint name="mex"  address="mex" kind="mexEndpoint" endpointConfiguration="standardMex" contract="RestSoapTest.IService1"/>
        <endpoint name="soap" address="soap" binding="basicHttpBinding" contract="RestSoapTest.IService1"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment>
      <serviceActivations>
        <add relativeAddress="RestSoapTest.svc" service="RestSoapTest.Service1"/>
      </serviceActivations>
    </serviceHostingEnvironment>
  </system.serviceModel>
  <system.web>
    <compilation debug="true"/>
  </system.web>
</configuration>

现在您可以浏览到:

/RestSoapTest.svc = SOAP 端点/帮助页面

/RestSoapTest.svc?wsdl = SOAP 元数据

/RestSoapTest.svc/help = 自动休息帮助页面

/RestSoapTest.svc/url/to/method = 执行 REST 动作

对于 Get 方法,请使用 WebGet 并确保 UriTemplate 中的参数计数与方法原型匹配,否则会出现错误

对于 Put 方法,使用 WebInvoke 并确保 UriTemplate 中的参数计数等于(原型中的计数 + 1)。

如果您这样做,WCF 框架将假定任何单个未映射的参数通过 HTTP Post 的请求正文进入。

如果需要多个参数通过 body 传入,则需要将参数格式设置为 Wrapped,默认为 Bare。Wrapped auto 在 parameterName/value 属性中封装了多个参数。

于 2014-05-19T10:54:12.603 回答