1

Currently we write contract first WCF SOAP services using .NET 3.5 and WSCF.blue. This allows us to design the Xml documents exchanged using Xsd files.

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:

Is it possible to upgrade to Visual Studio 2012, keep our existing Xsd set and automatically expose REST and/or SOAP endpoints?

Is it possible to upgrade to Visual Studio 2012, keep our existing Xsd set and automatically exchange Xml and/or Json documents?

Cœur
  • 37,241
  • 25
  • 195
  • 267
RoboJ1M
  • 1,590
  • 2
  • 27
  • 34

1 Answers1

0

Here's my solution:

You need Visual Studio 2012 minimum.

Create a WCF Service Library project.

Include your Xsd files to create data contract wrappers automatically.

Write your ServiceContract and class like this:

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)

Add a web host project, reference the WCF project and add this web.config file:

<?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?wsdl = SOAP metadata

/RestSoapTest.svc/help = automatic rest help page

/RestSoapTest.svc/url/to/method = Execute REST actions

For Get methods, use WebGet and ensure the parameter count in the UriTemplate and method prototype match otherwise you'll get an error

For Put methods, use WebInvoke and ensure that the parameter count in the UriTemplate equals (the count in the prototype + 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.

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 auto wraps up multiple parameters in parameterName/value properties.

RoboJ1M
  • 1,590
  • 2
  • 27
  • 34