You can implement .NET IDispatchMessageInspector for this work.
- Create a class implementing
IDispatchMessageInspector
- Create a class implementing
Attribute,IEndpointBehavior,IOperationBehavior
Allow only OPTIONS in your class implementing IDispatchMessageInspector
The code will look like this
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Collections.Generic;
using System.Net;
namespace WapstyPrintService
{
public class MessageInspector : IDispatchMessageInspector
{
private ServiceEndpoint _serviceEndpoint;
Dictionary<string, string> requiredHeaders;
public MessageInspector(ServiceEndpoint serviceEndpoint)
{
_serviceEndpoint = serviceEndpoint;
requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
}
/// <summary>
/// Called when an inbound message been received
/// </summary>
/// <param name="request">The request message.</param>
/// <param name="channel">The incoming channel.</param>
/// <param name="instanceContext">The current service instance.</param>
/// <returns>
/// The object used to correlate stateMsg.
/// This object is passed back in the method.
/// </returns>
public object AfterReceiveRequest(ref Message request,
IClientChannel channel,
InstanceContext instanceContext)
{
var httpRequest = (HttpRequestMessageProperty)request
.Properties[HttpRequestMessageProperty.Name];
return new
{
origin = httpRequest.Headers["Origin"],
handlePreflight = httpRequest.Method.Equals("OPTIONS",
StringComparison.InvariantCultureIgnoreCase)
};
}
/// <summary>
/// Called after the operation has returned but before the reply message
/// is sent.
/// </summary>
/// <param name="reply">The reply message. This value is null if the
/// operation is one way.</param>
/// <param name="correlationState">The correlation object returned from
/// the method.</param>
public void BeforeSendReply(ref Message reply, object correlationState)
{
var state = (dynamic)correlationState;
if (state.handlePreflight)
{
reply = Message.CreateMessage(MessageVersion.None, "PreflightReturn");
var httpResponse = new HttpResponseMessageProperty();
reply.Properties.Add(HttpResponseMessageProperty.Name, httpResponse);
httpResponse.SuppressEntityBody = true;
httpResponse.StatusCode = HttpStatusCode.OK;
}
var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
foreach (var item in requiredHeaders)
{
httpHeader.Headers.Add(item.Key, item.Value);
}
}
}
}
and
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace WapstyPrintService
{
public class BehaviorAttribute : Attribute, IEndpointBehavior,
IOperationBehavior
{
public void Validate(ServiceEndpoint endpoint) { }
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
{ }
/// <summary>
/// This service modify or extend the service across an endpoint.
/// </summary>
/// <param name="endpoint">The endpoint that exposes the contract.</param>
/// <param name="endpointDispatcher">The endpoint dispatcher to be
/// modified or extended.</param>
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher)
{
// add inspector which detects cross origin requests
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
new MessageInspector(endpoint));
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{ }
public void Validate(OperationDescription operationDescription) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{ }
public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{ }
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{ }
}
}
Then add your message inspector to service endpoint behavior
ServiceHost host = new ServiceHost(typeof(myService), _baseAddress);
foreach (ServiceEndpoint EP in host.Description.Endpoints)
EP.Behaviors.Add(new BehaviorAttribute());