I have a very old asmx webservice. Due to restrictions i cannot call this service directly. So i am creating a WCF web service, which will act like a proxy between the client and the actual web service. My client application, which was actually calling the asmx web service is now going to call the wcf service. Also this way, i should not make any code changes in my client.
I created the service successfully. While trying to access from my client, i get this message. The message with Action cannot be processed at the receive, due to a ContractFilter mismatch at the EndpointDispatcher.
I tried to match my proxy web service to match the existing webservice. May be i am missing something. Please help.
The ContractFilter mismatch is almost always due to versioning problems. You could try to update your "Connected Services" reference to WCF Service or manually rerun SvcUtil or use ChannelFactory of the ServiceContract of your WCF Service by putting this in a shared class library for the Client and the WCF service. You can also add more logging in WCF and use the util SvcTraceViewer to see where it fails. Add the following to the web.config of your WCF service for example:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\logs\messages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
Then you can open up the .svclog file in SvcTraceViewer and see why it fails. But if the client call already fails, it is possible that you will not see any log item anyways. So moving your Service Contract to a Shared class library and let the client use a ChannelFactory will ensure that your clients are more up to date with the service. Now it is also possible that it is the WCF service that fails a call against the older ASMX service, then firing up Fiddler is perhaps the next step (or add more logging in the old ASMX service).
I have a simple REST Web Service. I have tried to implement SimpleWebToken security therefor I created a custom SecurityTokenHandler with overridden CanreadToken and ReadToken then I registered it in web.cofig file.
<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<clear/>
<add type="TestTokens.SimpleWebTokenHandler, TestTokens"></add>
</securityTokenHandlers>
<audienceUris>
<clear/>
<add value="http://mytestrealm/"/>
</audienceUris>
</identityConfiguration>
I thought that CanReadToken() is always called, in order to make sure that the incoming request can be handled.
Why it is not called?
IFAIK, this collection of security handlers is only called when the WIF plumbing needs it. This can be p.e. when you offer a WS-Trust service. It is not called on all requests.
That is correct, WIF plumbing can be used to authenticate users. It looks like you are looking for more of a WebAPI solution. I would recommend using Jwt tokens as everyone seems to be leaning that way. Have a look here:
http://www.cloudidentity.com/blog/2013/06/06/the-json-web-token-handler-for-net-4-5-reaches-ga/
We put in some features that help when validating jwt's for WebAPI's.
I'm writing WCF services that will be used by clients out in the wild so they need to handle cross-origin requests. I have a problem with enabling my development server to accept such requests. Here is the scenario:
I'm running the WCF project in an instance of Visual Studio 2012, using IIS Express 8 as the server on a specific port.
I'm running the client project in another instance of Visual Studio 2012, also using IIS Express 8 as the server. This project uses AJAX to consume services in the other project.
When I run the client project in IE there is no problem because IE does not send the preflight OPTIONS request. When I run it in Chrome however the preflight OPTIONS request returns a 405 Method Not Allowed and Chrome gives up on the service. Previous versions of Chrome would just ignore the error and continue with the actual POST request (or Get, whatever...) but later versions appear to be pickier.
I've also run into this with a deployed WCF project and solved it by moving the OPTIONSVerbHandler to the top of the Handler Mappings list in IIS.
I should point out that I'm using the most generous web.config settings I can think of to try to allow CORS. For instance I have this in the WCF project's configuration:
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
<add name="X-Powered-By" value="*" />
</customHeaders>
</httpProtocol>
Regardless, any client cross-origin requests to the WCF project running from code fail with the 405 error.
Any help setting up either the WCF project itself or IIS Express 8 to enable CORS?
Thanks!
You can enable cors for wcf, and it could be quite simple, once you know how.
Elaborating from DavidG response on the more general question "cors on IIS", response which is really near of what is required for a basic solution:
First, configure the OPTIONSVerbHandler to execute before .Net handlers.
In IIS console, select "Handler Mappings". (Do this either on server level or site level. On site level it will redefine all the handlers for your site and ignore any change done on server level after that. And of course on server level, this could break other sites if they need their own handling of options verb.)
In Action pane, select "View ordered list...". Seek OPTIONSVerbHandler, and move it up (lots of clicks...).
You can also do this in web.config by redefining all handlers under <system.webServer><handlers>. (<clear> then <add ...> them back, this is what does the IIS console for you. By the way, there is no need to ask for "read" permission on this handler.)
Second, configure custom http headers for your cors needs, such as:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>
This example set them for all responses to all requests on the site/app/directory in which is the web.config. If you want to restrict them to some url, put that in a <location> tag.
You can also add those custom headers in IIS console.
This is a basic solution since it will send CORS headers even on request which does not require it, maybe opening your application to unexpected usages. But with WCF, it looks like being the simplest one.
With MVC or webapi, we could instead handle OPTIONS verb and cors headers by code (either "manually" or with built-in support available in latest version of webapi).
as a value is only valid for Access-Control-Allow-Origin. For the others you need to be explicit. For example:
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
or alternatively:
Access-Control-Allow-Methods: PUT, DELETE
because the spec says GET and POST are implied.
The answer is that the configuration needed to enable WCF to accept CORS preflight messages has nothing to do with the IIS server; rather the WCF project itself needs to be configured to handle the HTTP request with OPTIONS verb.
Long story short: doing this is REALLY HARD. WCF is a jack of all trades when it comes to endpoints so setting it up to do something very specific with one (HTTP) is not advisable, although it can be done. The real solution is to use Web API, which is a master of HTTP and can be set up to do CORS very simply.
I just wanted to mention, that as of this writing, I don't believe that web browsers support the * wildcard value for Access-Control-Allow-Methods or Access-Control-Allow-Headers even though it's in the spec.
Spec:
https://www.w3.org/TR/cors/
https://www.rfc-editor.org/rfc/rfc2616#section-4.2
See Compatibility Notes (easier reading):
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
In lieu of the above, better solutions, this means that you have to explicitly provide each and every header or method you want to allow.
I'm not sure this is really hard as djo.dadof2 says. One of the answers above talks about using the IIS console, but the question is about IIS Express. To be fair it talks about moving the OPTIONSVerbHandler higher which may in fact work in IIS Express, but you have to clear all the handlers and add them back, which without a console such as IIS has, is difficult as you don't know which ones to add back. From this answer, Call WCF service from JQuery : cross-origin OPTIONS request gives error 400, you can see that all you really need to do is handle the OPTIONS request in Global.asax.cs, Application_BeginRequest. I added
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "content-type");
HttpContext.Current.Response.End();
}
And together with
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="null" />
</customHeaders>
</httpProtocol>
in the webconfig system.webServer section that worked for me. Note that I used content-type in the Access-Control-Allow-Headers header to match what Firefox was sending, and null in the Access-Control-Allow-Origin as I was opening an html page from the local drive.
I have an ASP.NET WebApi application running locally using IISExpress that allows me to accept requests from any domain. I am doing this using a DelegatingHandler similar to the one provided one this blob post.
Locally this runs perfectly however after uploading to an Azure Website, I get the typical 'Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.' under Chrome.
I've tried to debug this by adding trace statements into the Handler with no output and it seems like SendAsync is never being executed, almost as if IIS is responding to the OPTIONS request instead of passing it on to my application.
Has anyone come across anything similar going from development to production?
IIS (including the one in your Azure web site) has a default OPTIONS handler. You will need to remove it in Web.config. It answers the OPTIONS call before your message handler has an opportunity to respond.
<configuration>
...
<system.webServer>
<handlers>
<remove name="OPTIONSVerbHandler" />
...
</handlers>
</system.webServer>
</configuration>
I'm able to run the WCF-SecureProfile sample that comes with the MSFT WCF samples download (http://msdn.microsoft.com/en-us/library/ee818238.aspx)
However I can't port this server component to IIS. I get the error that
<MakeConnectionBindingElement/> can't be loaded. Considering that I have the behavior extensions loaded I don't know why IIS can't see the extension, however the self-host version of my app can.
I uploaded the sourcecode of the project into codeplex for easy browsing. Here is a direct link to web.config and all other files.
2
I got the sample and set it up to run on IIS local. I didn't get the same issue as the one in this question but I did run into a big gotcha. Accessing the service in IIS gave me this error message:
Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it.
After some head scratching, I found the cause of this issue. WCF 4 now assigns default bindings to each transport (I'm liking this feature less & less). For the HTTP transport, the default binding is basicHttpBinding. The problem is the customBinding config does not override any default binding. This causes WCF to attempt to configure duplex over basicHttpBinding which of course isn't supported. The fix is to turn off the default transport mapping for HTTP and assign it to your custom binding as shown below for this service:
<protocolMapping>
<clear/> <!-- removes all defaults which you may or may not want. -->
<!-- If not, use <remove scheme="http" /> -->
<add scheme="http" binding="customBinding" bindingConfiguration="rspBinding"/>
</protocolMapping>
Once I added this to the serviceModel element, the IIS based service worked just fine.