This project is read-only.

Using the code

The current release contains samples for all the extensions. The WSDL extensions are injected through the .config file and the SOAP Headers using attributes in code.

Server side configuration

  • First, declare that you're using the WSDL Extras extension by adding this section to your config file:
<behaviorExtensions>
  <add name="wsdlExtensions" type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>

  • Add an endpointBehavior section and give it a name:
      <endpointBehaviors>
        <behavior name="Sample.WsdlSampleEndpointBehavior">
  • configure your endpoint to use that behavior:
      <service behaviorConfiguration="Sample.WsdlSampleBehavior" name="Sample.WsdlSample">
        <endpoint address="" behaviorConfiguration="Sample.WsdlSampleEndpointBehavior" ... />
      </service>
  • add a wsdlExtensions section inside that behavior and configure the options you want to use:
      <endpointBehaviors>
        <behavior name="Sample.WsdlSampleEndpointBehavior">
          <wsdlExtensions location="http://127.0.0.1/Sample/WsdlSample.svc" singleFile="true"/>
        </behavior>
      </endpointBehaviors>

  • If you want to override the enpoint URL, Set the location attribute to a url of your choice.
  • if you want the rendered WSDL file not to contain external references set the singleFile attribute to true.
see the web.config file in the SampleServer for the exact details.

To include XML comments in the rendered WSDL:

  • place an [XmlComments] attribute on your service contract (The interface marked with the [ServiceContract] attribute) and place xml comments on any service operation or DataContract you want to document:

    [XmlComments]
    [ServiceContract]
    public interface IWsdlSample
    {
        /// <summary>
        /// This is a simple operation without input paramaters.
        /// </summary>
        /// <returns>The operations returns a string</returns>
        [OperationContract]
        string Operation1();
    }

    /// <summary>
    /// A basic class marked with [DataContract]
    /// </summary>
    [DataContract]
    public class DataContractSample
    {
    ...
    }


To use SOAP header, follow these steps:

  • Place a [SoapHeaders] attribute on your Service Contract (The intreface with the [ServiceContract] attribute)
This marks this service as one that uses SOAP headers
  • Place a [SoapHeader] attribute on operation contracts that use SOAP headers:
        [SoapHeader("MyHeader", typeof(Header), Direction = SoapHeaderDirection.In)]
        [OperationContract]
        string In();

The first parameter is the name of the header. The second is the type that will represent this header. This type must have a [DataContract] attribute on it.
The third parameter specifies the direction of this header. valid values are In,Out,InOut.

Example header type:
    [DataContract]
    public class Header
    {
        [DataMember]
        public string Value { get; set; }
    } 

  • To access the header inside WCF calls use the SoapHeaderHelper class:
Accessing an "Input" direction header:
Header soapHeader = SoapHeaderHelper<Header>.GetInputHeader("MyHeader"); 
string value = soapHeader.value; 


Setting an "Output" direction header:
Header header=new Header();
header.value="Some value";
SoapHeaderHelper<Header>.SetOutputHeader("MyHeader", header);

Client side configuration

To configure clients to use the custom importers, you should first add a reference to the WCFExtras assembly on the client and then add a section to the client app.config file.

To generate XML comments from WSDL documentation on the client add the following section to your app.config file:

<system.serviceModel>
  <client>
    <metadata>
      <wsdlImporters>
        <extension type="WCFExtras.Wsdl.Documentation.XmlCommentsImporter, WCFExtras" />
        </wsdlImporters>
      </metadata>
    </client>
  </system.serviceModel>


To fine tune the WSDL comment import process you can add an <xmlComments> section to the app.config. See the SampleWCFClient app.config file for details.

To generate a client proxy that is "aware" of soap headers declared on the server add the following section to your app.config file:

<system.serviceModel>
  <client>
    <metadata>
      <wsdlImporters>
        <extension type="WCFExtras.Soap.SoapHeaderImporter, WCFExtras" />
        </wsdlImporters>
      </metadata>
    </client>
  </system.serviceModel>


extend the generated proxy by adding properties to the proxy class (Where "MyHeader" is the header name and Header is the class representing the header):
public partial class SoapHeadersSampleClient
{
  public Header MyHeader
  {
    get
    {
      return InnerChannel.GetHeader<Header>("MyHeader");
    }
    set
    {
      InnerChannel.SetHeader("MyHeader", value);
    }
  }
}


Now you can write code like the following:
client.MyHeader = new Header() { Value = "Test Input" }; //This will be automatically sent to the server in every request
string result = client.In(); 
//If a method on the server changes the value of the header, you can access the new value like this
result = client.MyHeader.Value;

Last edited Jan 25, 2009 at 1:05 PM by eyalp, version 6

Comments

MrKyaw May 20, 2013 at 9:54 AM 
Hi,

Now, I am facing big issue using WCF generated WSDL(using Add Service Reference in New Project) to generate stubs using Jax-WS.

Here is error message
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 1 of http://localhost:1234/wcfservice.svc?xsd=xsd1
[ERROR] <Related to above error>This is the other declaration.
line 1 of http://localhost:1234/wcfservice.svc?xsd=xsd2

Here is my code snippets below
//AddDataRequest.cs
namespace Sample
{
//[DataContract]
public class AddDataRequest
{
string id;

[DataMemberAttribute]
public string ID
{
get { return id; }
set { id = value; }
}
}
}

//AddDataResponse.cs
namespace Sample
{
[DataContract]
public class AddDataResponse
{
[DataMember]
public string retCode = "1";
}
}

//IData.cs
namespace Sample
{
[XmlComments]
[ServiceContract]
public interface IData
{
[OperationContract]
AddDataResponse AddData(AddDataRequest request);
}
}

//Data.svc.cs
namespace Sample
{
public class Sample: IData
{
public AddDataResponse AddData(AddDataRequest param1)
{
AddDataResponse addData= new AddDataResponse ();
return addData;
}
}

// web.config
<?xml version="1.0"?>

<configuration>
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
<section name="xmlComments" type="WCFExtras.Wsdl.Documentation.XmlCommentsConfig, WCFExtras"/>
</configSections>
<appSettings/>
<connectionStrings/>

<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>

<authentication mode="Windows"/>

<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>

<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>

<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>

</system.web>

<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>

<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>

<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>

<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</handlers>

<directoryBrowse enabled="true" />
</system.webServer>

<system.serviceModel>
<services>

<service behaviorConfiguration="Sample.DataBehavior" name="Sample.DataService">
<endpoint address="" behaviorConfiguration="Sample.DataEndpointBehavior" binding="basicHttpBinding" contract="Sample.IData"/>
</service>

</services>

<behaviors>

<endpointBehaviors>
<behavior name="Sample.DataEndpointBehavior">
<wsdlExtensions location="http://localhost/Sample/Data.svc"/>
</behavior>
</endpointBehaviors>

<serviceBehaviors>
<behavior name="Sample.DataBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>

</behaviors>

<extensions>
<behaviorExtensions>
<!-- Declare that we have an extension called WSDL Extras-->
<add name="wsdlExtensions" type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>

</configuration>
Even, I tried in VS 2012 but still the same issue. Could it be possible coz of WSDL flattening or something else?

I hope some one will advise me to close the case since I am running out of time.



Thanks and best regards

SabbeRubbish Nov 12, 2012 at 11:16 AM 
You write
"First, declare that you're using the WSDL Extras extension by adding this section to your config file:"
Maybe I'm just to new to this stuff, but it would be handy stating that it should be added under
<system.serviceModel>
<extensions>

rlesias Nov 8, 2011 at 5:17 PM 
In the Server Side Configuration, the statement behaviorConfiguration="Sample.WsdlSampleBehavior" is not required and causes confusing errors at runtime.

<service behaviorConfiguration="Sample.WsdlSampleBehavior" name="Sample.WsdlSample">
<endpoint address="" behaviorConfiguration="Sample.WsdlSampleEndpointBehavior" ... />
</service>

I removed it and now everything works fine