Simplest service in one .svc file

<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceSimpleNs.WcfServiceSimple" %>

using System;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WcfServiceSimpleNs
{
  [ServiceContract]
  public interface IWcfServiceSimple
  {
    [OperationContract]
    string GetData(int value);
  }

  public class WcfServiceSimple : IWcfServiceSimple
  {
    public string GetData(int value)
    {
      return string.Format("Simplest: Argument passed: {0}", value);
    }
  }
}


More info and samples on: www.devarchweb.net

What type of application pool needs to be used Make sure that you select the AppPool with Integrated Pipeline mode
(When you use classic you wil get 500.21 Error)
HTTP-Fehler 500.21 - Internal Server Error, Der Handler '.svc' weist das ungueltige Modul ManagedPipelineHandler in der Modulliste auf.

More info and samples on: www.devarchweb.net

Minimum config file Note: if you do not have any service listed in your config at all, when debugging from Visual Studio with IIS Express
or when hosting in IIS, the hosting server will detect if a service is available and expose it with basicHttpBinding

<configuration>
  <system.serviceModel>

    <services>
      <!-- Note: the service name must match the configuration name for the service implementation. -->
      <service
        name="WcfServiceSimpleNs.WcfServiceSimple"
        behaviorConfiguration="MyServiceTypeBehaviors" >

        <endpoint
          address=""
          binding="wsHttpBinding"
          contract="WcfServiceSimpleNs.IWcfServiceSimple" />

      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceTypeBehaviors" >

          <serviceMetadata httpGetEnabled="true" />

        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>
</configuration>


More info and samples on: www.devarchweb.net

Disable WSDL

<serviceMetadata httpGetEnabled="false" />


More info and samples on: www.devarchweb.net

From which file reads service its configuration (selfhosted and IIS) Be aware that the when the service is hosted by IIS then the service reads its System.ServiceModel configuration
from web.config, not from MyService.dll.config,
that gets created by Visual Studio. MyService.dll.config would be used if the service is selfhosted.

More info and samples on: www.devarchweb.net

What is called ABC Address - specify location of the service. Client will need to set this to URL of the service.
Binding - defines how client communicates with the service (SOAP, REST, ..)
Contract - defines data transferred (IWcfServiceSimple interface)

More info and samples on: www.devarchweb.net

Binding types basicHttpBinding - SOAP 1.1 (weak security; great on intercompatilibility
wsHttpBinding - SOAP 1.2 (security, reliable messiging, sessionfull connections; heavier
webHttpBinding - REST (does not require a SOAP client to access the messages, XML or JSON retuned based on URL)
netTcpBinding - optimized and faster than wsHttpBinding, secure, intended for WCF-to-WCF communication

basicHttpBinding,wsHttpBinding webHttpBinding
basicHttpBinding vs. wsHttpBinding

All bnding types on MSDN

More info and samples on: www.devarchweb.net

What are the deployment options 1. one embeded file (described above)
2. .svc and .svc.cs file. You can split the .svc file above to WcfSimple.svc

<%@ ServiceHost Language="C#" Debug="true" Service="WcfServiceSimpleNs.WcfServiceSimple" %>


and \App_Code\WcfServiceSimple.svc.cs files.

using System;
...
namespace WcfServiceSimpleNs
{
  public interface IWcfServiceSimple { ... }

  public class WcfServiceSimple : IWcfServiceSimple { ... }
}


3. You can compile .svc.cs to a .net dll binary (from Visual Studio or command line) and copy it to \bin folder of the web service.


You may need to run c:\Windows\Microsoft.NET\Framework64\v3.0\Windows Communication Foundation\ServiceModelReg.exe -i to install WCF components.

More info and samples on: www.devarchweb.net

Create self host for WCF service 1. Create console application
2. add reference to System.ServiceModel

 // Must be executed with VS running As Administrator
 static void Main(string[] args)
 {
   Uri baseSvcAddress = new Uri("http://localhost:9000/MyServiceHost");

   // Create the host
   using (ServiceHost host = new ServiceHost(typeof(WcfServiceSimple), baseSvcAddress))
   {
     // Enable metadata
     ServiceMetadataBehavior svcMetadataBehavior = new ServiceMetadataBehavior();
     svcMetadataBehavior.HttpGetEnabled = true;
     svcMetadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
     host.Description.Behaviors.Add(svcMetadataBehavior);

     // base service address will be used.
     host.Open();

     Console.WriteLine("The service is running at {0}", baseSvcAddress);
     Console.WriteLine("Press 'Enter' to stop the service.");
     Console.ReadLine();

     // Close the host.
     host.Close();
   }
 }


More info and samples on: www.devarchweb.net

How to create WCF service client Consuming WCF service:

When developing in Visual Studio
In order to be able to create a client with a proxy, you do not need to deploy the service
1. In the same solution as the service project is located, Create a New project (e.g. a Console app)
2. Right click on References and select "Add Service Reference .."
3. Click "Discover/Service in Solution"

When consuming a public service
3. Enter the url of the running wcf service and click Go

4. Visual Studio will generate a Service References folder with a subfolder for your wcf service with about 9 files.
Reference.cs file that represents the proxy to the service is created under the subfolder.

// create client using defined configuration from
using (var client = new WcfServiceSimpleClient("BasicHttpBinding_IWcfServiceSimple"))
{
// call a service method with 1 argument
string result = client.GetData(2);
}


More info and samples on: www.devarchweb.net

Create client without service reference and app.config It is possible to create a client and call his methods without specifying parameters in config file
and creating webservice reference. The service interface is needed.

// create channel
var myBinding = new WebHttpBinding();
var myEndpoint = new EndpointAddress("http://myurl.net");
var channelFactory = new ChannelFactory<IMyInterface>(myBinding, myEndpoint);
channelFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());
IComplianceFacade client = null;

client = channelFactory.CreateChannel();

// make the call
client.MyMethod();

// close channel
channelFactory.Close();


More info and samples on: www.devarchweb.net

How to debug the WCF service from Visual Studio - In Visual Studio, in Solution Explorer, click on the .svc file.
- Press F5, WCF Test Client will be opened (VS 2013).
- Put a break point into the method that you want to debug
- Select the method in the left panel and click Invoke

Note 1: the service output must be in bin\ folder
Note 2: the <UseIIS> flag in .csproj file must be set to "true" in order the test client starts
Note 3: if you have your own client in the same solution, you can either start both the service and
your own client by right clicking on the solution and selecting "Set StartUp Projects..." or just select
the client as startup project and VS will start IIS with Service automatically
Note 4: you need to have an endpoint that exposes SOAP based binding (BasicHttpBinding or wsHttpBinding) to see the service in WCF Test Client
Note 5: Visaul Studio starts IIS Express. Make sure that it gets closed before you start the updated service
(right on the IIS Express icon in the Task bar, click Exit).

MSDN Blog:Using WCF test client

More info and samples on: www.devarchweb.net

What is the purpose of web.config|web.debug.config|web.release.config The same section in web.config gets replaced with content of web.release.config or web.release.config
(with help of xlst transformation) when the service gets deployed from Visual Studio (2013) using Publish action.

This will not happen during build (F5 in Visual Studio).

Usage:
It is useful e.g. for replacing connection string (from local dev DB used during development when
starting the service from Visual Studio) to production DB when deploying to production.

web.config

<connectionStrings>
 <add name="MyDB"
  connectionString="Data Source=.;Initial Catalog=DevelopmentDB;Integrated Security=True" />
</connectionStrings>
</code>



web.release.config

<connectionStrings>
 <add name="MyDB"
connectionString="Data Source=ProductionSQLServer;Initial Catalog=ProductionDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>



If the the same action is required to happen during build, there are multiple ways how to run the transformation
described here.

More info and samples on: www.devarchweb.net

Format of transmitted data - simple types For the method below using simple data types

public string MyMethod(int myIntValue, string myStringValue)
{
return string.Format("Arguments passed: {0} {1}", myIntValue, myStringValue);
}



here is data send as request:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Header>
  <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IWcfServiceSimple/MyMethod</Action>
 </s:Header>
 <s:Body>
  <MyMethod xmlns="http://tempuri.org/">
   <myIntValue>2</myIntValue>
   <myStringValue>abc</myStringValue>
  </MyMethod>
 </s:Body>
</s:Envelope>



and as response:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Header />
 <s:Body>
  <MyMethodResponse xmlns="http://tempuri.org/">
   <MyMethodResult>Arguments passed: 2 abc</MyMethodResult>
  </MyMethodResponse>
 </s:Body>
</s:Envelope>


More info and samples on: www.devarchweb.net

Format of transmitted data - composite types For the method below using composite data types

[DataContract]
public class MyCompositeType
{
bool boolValue = true;
string stringValue = "Hello ";

[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}

[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}

public MyCompositeType GetDataUsingDataContract(MyCompositeType composite)
{
return composite;
}



here is data send as request:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Header>
  <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IWcfServiceSimple/GetDataUsingDataContract</Action>
 </s:Header>
 <s:Body>
  <GetDataUsingDataContract xmlns="http://tempuri.org/">
   <composite xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfServiceSimple" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <d4p1:BoolValue>false</d4p1:BoolValue>
    <d4p1:StringValue>abc</d4p1:StringValue>
   </composite>
  </GetDataUsingDataContract>
 </s:Body>
</s:Envelope>



and as response:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
 <s:Header />
 <s:Body>
  <GetDataUsingDataContractResponse xmlns="http://tempuri.org/">
   <GetDataUsingDataContractResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfServiceSimple" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <a:BoolValue>false</a:BoolValue>
    <a:StringValue>abc</a:StringValue>
   </GetDataUsingDataContractResult>
  </GetDataUsingDataContractResponse>
 </s:Body>
</s:Envelope>


More info and samples on: www.devarchweb.net

How to enable exception details (2 options) 1. In code

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class WcfServiceSimple : IWcfServiceSimple



2. config file


<system.serviceModel>
  <services>
   <service name="ServiceNamespace.ServiceClassName" behaviorConfiguration ="DebugEnabled">
   </service>
  </services>
  <behaviors>
   <serviceBehaviors >
    <behavior name="DebugEnabled">
     <serviceDebug includeExceptionDetailInFaults="True"/>
    </behavior>
   </serviceBehaviors>
  </behaviors>
 <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>


More info and samples on: www.devarchweb.net

How to configure large WCF messages

<system.serviceModel>
 <bindings>
  <netTcpBinding>
   <binding name="largeMessageBinding"
    receiveTimeout="00:10:00"
    sendTimeout="00:10:00"
    maxReceivedMessageSize="1000485760"
    >
    <readerQuotas maxArrayLength="1000485760"/>
   </binding>
  </netTcpBinding>
 </bindings>

 <services>
  <service
   name="largeMessageService"
   <endpoint
     binding="netTcpBinding"
     bindingConfiguration="largeMessageBinding"
     ... />
  </service>
 <services>
</system.serviceModel>


More info and samples on: www.devarchweb.net

What happens if new field is added to composite type or an old field is renamed If you add a new field as last field to a composite type on the service side and do not update the composite type on the client side, you can still call
the service and the fields of the composite type defined in the proxy used by the client will be populated.

If you change the name of a field on the server side, you can still make a call, but the old name on the client side will not be populated.

The same applies if the composite type is passed as an argument or a return type.

More info and samples on: www.devarchweb.net

How to inject WCF service with Unity (2.options) Install Unity Nuget package
(it will add 3 Microsoft.Practices.Unity.*.dlls and Microsoft.Practices.ServiceLocation.dll)

Assuming you have a class that connects to an external repository (e.g. a database) and you want to mock the call for testing.

public interface IExternalRepository
{
int GetData();
}

public class ExternalRepository : IExternalRepository
{
public int GetData()
{
int result = // read from a database
return result;
}
}


and a service depending on the repository

public class MyUnityService : IWcfServiceSimple
{
public string GetData()
{
return _externalRepository.GetData();
}
}



There are 2 options how to let unity to inject the classes:

1. Create Dependency Injection Factory with static constructor and add contructor to EACH dependency class

using Microsoft.Practices.Unity;
public class DependencyFactory
{
private static IUnityContainer _container { get; set; }

static DependencyFactory()
{
_container = new UnityContainer();
container.RegisterType<IExternalRepository, ExternalRepository>();
}

public static T Resolve<T>()
{
T result = default(T);
if (_container.IsRegistered(typeof(T)))
{
result = _container.Resolve<T>();
}
return result;
}
}


and add static constructors to the WCF service

public class MyUnityService : IWcfServiceSimple
{
private readonly IExternalRepository _externalRepository;

public MyUnityService() : this(DependencyFactory.Resolve<IExternalRepository>())
{
}

public MyUnityService(IExternalRepository externalRepository)
{
_externalRepository = externalRepository;
}

public string GetData()
{
return _externalRepository.GetData();
}
}


The example above demonstrates what happens behind the scene in the option #2.

2. Use Factory attribute in .svc file.

<%@ ServiceHost Language="C#" Debug="true" Factory="WcfServiceSimpleNs.WcfServiceHostFactory"
 Service="WcfServiceSimpleNs.WcfServiceSimple2" CodeBehind="WcfServiceSimple2.svc.cs" %>


This requires to write a class inherited from ServiceHost

public partial class WcfServiceHost : ServiceHost
{
public WcfServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
: base(container.Resolve(serviceType), baseAddresses)
{
}

public WcfServiceHost(IUnityContainer container, Type serviceType)
: base(container.Resolve(serviceType))
{
}
}


and the factory inherited from ServiceHostFactory

public class WcfServiceHostFactory : ServiceHostFactory
{
private readonly IUnityContainer _container;

public WcfServiceHostFactory()
{
_container = new UnityContainer();
_container.RegisterType<IExternalRepository, ExternalRepository>();
}

protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new WcfServiceHost(_container, serviceType, baseAddresses);
}
}


The service must be marked with

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class WcfServiceSimple2 : IWcfServiceSimple2
{
}


In both cases, when the WCF service class gets instatiated, the dependency classes (ExternalRepository) will be injected.

The second case does not require to write special constructors for each dependency class.

More info and samples on: www.devarchweb.net

Turn off authentication

<system.serviceModel>
 <bindings>
  <wsHttpBinding>
   <binding name="CustomBinding">
    <security mode="None">
     <message establishSecurityContext="false"/>
     <transport clientCredentialType="None"/>
    </security>
   </binding>
  </wsHttpBinding>
 </bindings>

 <service>
  <endpoint
    ...
    binding="wsHttpBinding"
    bindingConfiguration="CustomBinding"
    >
  </endpoint>
 </service>
....
<system.serviceModel>




In code:

WSHttpBinding wsb = new WSHttpBinding(SecurityMode.Message, false);
wsb.Security.Transport.ClientCredentialType = MessageCredentialType.None;
wsb.Security.Message.EstablishSecurityContext = false;


More info and samples on: www.devarchweb.net

install certificate in local machine storage The standard installation with double click on the certificate file is not the right installation procedure
if you need a certificate be accessible by a service. The it is necessary:


Start mmc
Go to File / Add/Remove Snap-in...
Double click on Certificates
Select Computer account, Next, Finish, OK
In Console Window right click on Certificates/Personal/Certificates
Select All Tasks/Import
Select your certificate file from



ASP.net roles configuration in Visual Studio 2013

MSDN Article
As the menu Website | ASP.NET Configuration is not available in Visual studio 2013, you can invoke the configuration web site manually:


Start IIS express (not as admin) - works with .net 4
iisexpress.exe /path:C:\Windows\Microsoft.NET\Framework\v4.0.30319\ASP.NETWebAdminFiles /vpath:"/ASP.NETWebAdminFiles" /port:8082 /clr:4.0 /ntlm

Open ASP configuration (d:\mySolutionFolder is the path where .sln is located)
http://localhost:8082/asp.netwebadminfiles/default.aspx?applicationPhysicalPath=d:\mySolutionFolder\&applicationUrl=/

You will be ask to enter your Windows credentials. If you are logged to the domain, your full user name will look like "domainName\userName"



http://stackoverflow.com/questions/32116493/cs0122-system-configuration-stringutil-is-inaccessible-due-to-its-protection


If you see the error (probably after VS 2015 installed):
Compiler Error Message: CS0122: 'System.Configuration.StringUtil' is inaccessible due to its protection level

Replace Line 989 in C:\Windows\Microsoft.NET\Framework\v4.0.30319\ASP.NETWebAdminFiles\WebAdminPage.cs

string appId = (String.Concat(appPath, appPhysPath).GetHashCode()).ToString("x", CultureInfo.InvariantCulture);

More info and samples on: www.devarchweb.net

ASP.net configuration in Visual Studio 2013 Start IIS express (not as admin) - works with .net 4
iisexpress.exe /path:C:\Windows\Microsoft.NET\Framework\v4.0.30319\ASP.NETWebAdminFiles /vpath:"/ASP.NETWebAdminFiles" /port:8082 /clr:4.0 /ntlm

Open ASP configuration (d:\mySolutionFolder is the path where .sln is located)
http://localhost:8082/asp.netwebadminfiles/default.aspx?applicationPhysicalPath=d:\mySolutionFolder\&applicationUrl=/

You will be ask to enter your Windows credentials. If you are logged to the domain, your full user name will look like "domainName\userName"

More info and samples on: www.devarchweb.net

Assign certificate to client in code

using System.Security.Cryptography.X509Certificates;

var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificatesFound = store.Certificates.Find(X509FindType.FindBySubjectName, (object)"MyCertificateName", true);
store.Close();
channelFactory.Credentials.ClientCertificate.Certificate = certificatesFound[0];


More info and samples on: www.devarchweb.net

Add http header to request Adding a header to request requires to implement IClientMessageInspector and IEndpointBehavior

public class HttpHeaderEndpointBehavior : IEndpointBehavior
{
private readonly IDictionary<string, string> _headers;

public HttpHeaderEndpointBehavior(IDictionary<string, string> headers)
{
_headers = headers;
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
var inspector = new HttpHeaderClientMessageInspector(_headers);
clientRuntime.MessageInspectors.Add(inspector);
}

// implementation of abstract nmethods
public void Validate(ServiceEndpoint endpoint) { }
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
}

public class HttpHeaderClientMessageInspector : IClientMessageInspector
{
private readonly IDictionary<string, string> _headers;

public HttpHeaderClientMessageInspector(IDictionary<string, string> headers)
{
_headers = headers;
}

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;

if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (httpRequestMessage != null)
{
foreach (var h in _headers)
{
httpRequestMessage.Headers[h.Key] = h.Value;
}
}
}

return null;
}

public void AfterReceiveReply(ref Message reply, object correlationState) { }
}


// add header to channel factory before creating the channel
// HttpHeaderEndpointBehavior will be called before each request

var headerDict = new Dictionary<string, string>();
headerDict.Add("MyHeaderKey", "MyHeaderValue");
facadeChannelFactory.Endpoint.Behaviors.Add(new HttpHeaderEndpointBehavior(headerDict));





More info and samples on: www.devarchweb.net