For background information, see part 1
For message inspection code, see part 2
For operation dispatcher code, see part 3
To include the message inspection in our wcf service for our service we need to bind it to our service. This is done using behaviors. To bind the IDispatchMessageInspector that works on the ServiceEndpoint level we need to implement an IEndpointBehavior and assign it to our endpoint.
To bind the IOperationInvoker and IDispatchMessageFormatter we need to implement the IOperationBehavior that works on the operation level.
This class also works as an attribute so you can decorate your contract and operations with it if need be. It also contains some properties if you want to control the header values.
https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsBehaviorAttribute.cs
https://github.com/dhvik/Wcf-cors-behavior/blob/master/CorsBehaviorAttribute.cs
Assigning can be done in many ways. By declarations on the contract (attribute), configuration in the applications configuration file or direct using code. I'm using code since I host the services in a windows service.
var host = new WebServiceHost2(serviceType, false, new Uri(serviceBaseUrl + serviceName)); var endpoint = host.AddServiceEndpoint(contractType, new WebHttpBinding(WebHttpSecurityMode.None), ""); //add support for cors (both for the endpoint to detect and create reply) endpoint.Behaviors.Add(new CorsBehaviorAttribute()); foreach (var operation in endpoint.Contract.Operations) { //add support for cors (and for operation to be able to not //invoke the operation if we have a preflight cors request) operation.Behaviors.Add(new CorsBehaviorAttribute()); }When we now have all pieces in place we don't need to bother about cross domain requests. Our endpoint and operation behaviors handles this and we don't need to litter our service code with things that don't belong there anyway.
Thanks for posting this great article. Would you please add a sample web.config as well to connect all these together?
ReplyDeleteDav
If you host it in the IIS, you can decorate your service interface and methods with the CorsBehaviorAttribute like
ReplyDelete[ServiceContract]
[CorsBehavior]
interface IMyService {
[OperationContract]
[CorsBehavior]
string MyMethod(string);
}
Hi
Deletetring this and still get Cross Domain JavaScript CallBack is not supported in authenticated services.
(When I Browse to the WCF address https://SERVERNAME:5554/MyWCFSERVICE.SVC)
I used the attributes as you recomended.
Thank you Dan for the quick response. Will implement and let you know..
ReplyDeleteHi Dan ..
ReplyDeleteDid you have happen to have a test client calling the service using Jquery. tried the same and having some issue. Doing some research now, thought I will ask here as well
Jquery works fine but if you use ie you have to set $.support.cors = true;
ReplyDeleteDoes this need to be configured in the web.config at all?
ReplyDeleteMy requests seem to fail when I decorate my interface adn mehtods:
ReplyDeletefurniture
localhost/SeatingPlanner.svc/Wayneprjatk-Com/plans-1
OPTIONS
(failed)
undefined
jquery.js:16
Script
22B
0B
2.08s
0.0 days
The cors solution uses two behaviors, one Endpoint and one operation behavior.
ReplyDeleteThe Operation behavior can be added using the attribute on the operation. The endpoint behavior can not be added using the attribute but needs to be configured in the config file or programmatically (as in my example where I configure both operation and endpoint behaviors by code.
See http://msdn.microsoft.com/en-us/magazine/cc163302.aspx and the section Adding Behaviors with Attributes and Configuration for more information on how to add behaviors using the config file.
ReplyDeleteHi, I am using a REST call to the Service from Client using JQuery. So the HTTP Header contains the REST URI and not the WCF.
ReplyDeleteIn the method "AfterReceiveRequest" when we process for the Method "Options" it tries to match what are the options available on the operations and it doesnt find resulting in unknown response. Can u help me in solving this issue.
Hi, I found the issue, i was using PUT verb, hence is the problem. Please ignore my previous query.
ReplyDelete