简体   繁体   English

是否可以先签约WCF并公开REST / JSON和SOAP / XML端点?

[英]Is it possible to do contract first WCF and expose REST/JSON and SOAP/XML endpoints?

Currently we write contract first WCF SOAP services using .NET 3.5 and WSCF.blue. 当前,我们使用.NET 3.5和WSCF.blue编写合同优先的WCF SOAP服务。 This allows us to design the Xml documents exchanged using Xsd files. 这使我们可以设计使用Xsd文件交换的Xml文档。

Now that WSDL 2.0 exists and you can design contracts for REST endpoints and there is proper support for contract first in .NET 4.5 we have the following questions: 现在,WSDL 2.0已经存在,您可以为REST端点设计合同,并且.NET 4.5中首先对合同有适当的支持,我们有以下问题:

Is it possible to upgrade to Visual Studio 2012, keep our existing Xsd set and automatically expose REST and/or SOAP endpoints? 是否可以升级到Visual Studio 2012,保留我们现有的Xsd并自动公开REST和/或SOAP端点?

Is it possible to upgrade to Visual Studio 2012, keep our existing Xsd set and automatically exchange Xml and/or Json documents? 是否可以升级到Visual Studio 2012,保留我们现有的Xsd集并自动交换Xml和/或Json文档?

Here's my solution: 这是我的解决方案:

You need Visual Studio 2012 minimum. 您至少需要Visual Studio 2012。

Create a WCF Service Library project. 创建一个WCF服务库项目。

Include your Xsd files to create data contract wrappers automatically. 包括您的Xsd文件以自动创建数据合同包装器。

Write your ServiceContract and class like this: 像这样编写您的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; }
    }
}

(Either write your DataContract by hand or control it with an Xsd) (或者手动编写DataContract,或者使用Xsd对其进行控制)

Add a web host project, reference the WCF project and add this web.config file: 添加一个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>

Now you can browser to: 现在,您可以浏览到:

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

/RestSoapTest.svc?wsdl = SOAP metadata /RestSoapTest.svc?wsdl = SOAP元数据

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

/RestSoapTest.svc/url/to/method = Execute REST actions /RestSoapTest.svc/url/to/method =执行REST操作

For Get methods, use WebGet and ensure the parameter count in the UriTemplate and method prototype match otherwise you'll get an error 对于Get方法,请使用WebGet并确保UriTemplate中的参数计数与方法原型匹配,否则会出现错误

For Put methods, use WebInvoke and ensure that the parameter count in the UriTemplate equals (the count in the prototype + 1). 对于Put方法,请使用WebInvoke并确保UriTemplate中的参数计数等于(原型中的计数+ 1)。

If you do this, any single un-mapped parameter will be assumed by the WCF framework to be coming in through the HTTP Post's Request body. 如果执行此操作,则WCF框架将假定任何单个未映射的参数都通过HTTP Post的Request主体传入。

If you need more than one parameter coming in through the body, you need to set the parameter format to Wrapped, it defaults to Bare. 如果需要通过主体输入多个参数,则需要将参数格式设置为Wrapped,默认为Bare。 Wrapped auto wraps up multiple parameters in parameterName/value properties. 包装的自动包装在parameterName / value属性中的多个参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM