Wednesday, December 12, 2012

JSONP WCF service over SSL

In .NET Framework 3.5 JSONP message encoding is not available out of the box. In this short post I will show how to configure WCF to support JSONP endpoint over SSL. You can use extension which is available here to get support for JSONP in WCF in .NET Framework 3.5.

You will need to extract following files:
  • JSONPBehavior.cs
  • JSONPBindingElement.cs
  • JSONPBindingExtension.cs
  • JSONPEncoderFactory.cs
and add them to your project

Let's assume that we have following contract

namespace MyService
{
 public interface IRestService
 {
  [OperationContract]
  [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetInfo?clientInfo={clientInfo")]
  [JSONPBehavior(callback = "method")]
  string GetInfo(string clientInfo);
 }
}

and implementation

namespace MyService
{
 [AspNetCompatibilityRequirements(RequirementsMode = 
 AspNetCompatibilityRequirementsMode.Required)]
 public class RestService : IRestService
 {
  string GetInfo(string clientInfo)
  {
   return string.Format("Client info {0}", clientInfo);
  }
 }
}

and we would like to expose this method via JSONP endpoint over SSL. First thing is to register new binding element extension

<bindingElementExtensions>
 <add name="jsonpMessageEncoding" 
     type="Microsoft.Jsonp.JsonpBindingExtension, Microsoft.Jsonp, 
  Version=1.0.0.0, Culture=neutral, PublicKeyToken=..."/>
</bindingElementExtensions>
and define endpoint behaviour
<endpointBehaviors>
 <behavior name="RestService.EndpointBehavior">
  <webHttp/>
 </behavior>
</endpointBehaviors>

the next thing is to create custom binding. This is the place where you can decide if you would like to expose your future endpoint over http or https

<customBinding>
 <binding name="jsonpBinding_RestService_SSL">
  <jsonpMessageEncoding/>
     <httpsTransport manualAddressing="true"/>
  </binding>
</customBinding>

if you use <httpsTransport manualAddressing="true"/> you will be able to expose your endpoint via SSL. If you would like to have your mex endpoint also avilable via SSL you need to modify service behaviour with

<serviceMetadata httpsGetEnabled="true"/>

Last task is to create endpoint

<endpoint address="https://localhost/RestService/RestService.svc/JSONPRestService" 
    binding="customBinding" 
 bindingConfiguration="jsonpBinding_RestService_SSL" 
 name="jsonP_RestService_SSL" 
 contract="MyService.IRestService" 
 behaviorConfiguration="RestService.EndpointBehavior"/>

Final configuration looks in following way

<system.serviceModel>
 <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
 <bindings>
  <customBinding>
   <binding name="jsonpBinding_RestService_SSL">
    <jsonpMessageEncoding/>
    <httpsTransport manualAddressing="true"/>
   </binding>
  </customBinding>
    </bindings>
    <behaviors>
  <serviceBehaviors>
   <behavior name="MyService.RestServiceBehavior">
    <serviceMetadata httpsGetEnabled="true"/>
   </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
   <behavior name="RestService.EndpointBehavior">
    <webHttp/>
   </behavior>
  </endpointBehaviors>
    </behaviors>
    <extensions>
  <bindingElementExtensions>
   <add name="jsonpMessageEncoding" 
        type="Microsoft.Jsonp.JsonpBindingExtension, 
           Microsoft.Jsonp, Version=1.0.0.0, 
        Culture=neutral, PublicKeyToken=..."/>
  </bindingElementExtensions>
    </extensions>
    <services>
  <service behaviorConfiguration="MyService.RestServiceBehavior" 
              name="MyService.RestService">
   <endpoint address="https://localhost/RSrv/RSrv.svc/JSONPRestSrv" 
                binding="customBinding" 
       bindingConfiguration="jsonpBinding_RestService_SSL" 
       name="jsonP_RestService_SSL" 
       contract="MyService.IRestService" 
       behaviorConfiguration="RestService.EndpointBehavior"/>
   <endpoint address="mex" 
       binding="mexHttpBinding" 
       name="mexHttp_RestService" 
       contract="IMetadataExchange" />
  </service>
    </services>
</system.serviceModel>  


And this is it. I hope this will be helpfull and will save some time.

No comments:

Post a Comment