WCF service - Minimum required web.config? - wcf

I have a simple WCF service (hosted as its own site in IIS). It was originally developed targeting .NET 4 but I have recently discovered that it needs to be downgraded to .NET 3.5.
I never touched the web.config file and it Just Worked. Now that I've changed the project from .NET 4 back to 3.5 I'm getting config errors. The first one was about multipleSiteBindingsEnabled not being recognised - a quick search tells me this is new in .NET 4 so I just deleted it. Now the error I'm getting is:
Service 'MyService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
I just want to get the service responding so I can test firing things at it. The system that will be consuming the service doesn't exist yet (it's currently being developed by a government department) so once that's closer to completion we'll be worrying about the config that will be needed for it to go into production etc. What's the minimum config I need in the web.config to make it work for testing?

You need these basic nodes in your service's web.config files usually.
Of Course the binding types / dedub config / etc is all just for testing.
You need to fine tune it as per your needs
<system.serviceModel>
<services>
<service name="A.B.C.D" behaviorConfiguration="returnFaults">
<endpoint contract="A.B.C.ID" binding="basicHttpBinding" address=""/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="HttpBinding" maxReceivedMessageSize="2097152">
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="returnFaults">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

Related

('IntegratedWindowsAuthentication') do not allow those configured on the binding 'WebHttpBinding' ('Anonymous')

I follow this (https://bishwaranjan.wordpress.com/2014/09/05/how-to-upload-files-using-kendo-file-upload-and-wcf-service/) article step by step, but I have the following exption:
The authentication schemes configured on the host ('IntegratedWindowsAuthentication') do not allow those configured on the binding 'WebHttpBinding' ('Anonymous'). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.
I ran into this issue on my dev box this afternoon using Visual Studio 2013 community edition.
My solution was to single click the project name, then change Properties > Development Server > Anonymous Authentication to "Enabled".
Here is a copy of my web.config file as well:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="RiddenGear.AJAX.GuestServicesAspNetAjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service name="RiddenGear.AJAX.GuestServices">
<endpoint address="" behaviorConfiguration="RiddenGear.AJAX.GuestServicesAspNetAjaxBehavior" binding="webHttpBinding" contract="RiddenGear.AJAX.GuestServices"/>
</service>
</services>
</system.serviceModel>
As a side bar, please note that this is my dev config. We do run another config for live that forces connections over https. Once you get things rolling in dev you'll likely want to upgrade your config to handle these connections as well.

Converting "HelloWorld" WCF Web Service to use https?

It's really hard to pick up web services if you're a beginner, not because the concept is hard - it isn't - but because the technology has gone through a lot of twists and turns and googling for help doesn't help if all you get back are answers for implementations done slightly differently.
[For example our solution has never had a .svc file or .asmx file though those turn up regularly in answers and our web.config doesn't have any behavior or binding element, as others seem to have]
We've used a tutorial to set up what I think is termed a "WCF Web Service" running on IIS6. It's working fine.
But we'd like to convert it to use encryption/https.
So we've checked the Require secure channel box in IIS:
Not sure what else to configure in there, but ... anyway, moving on. Next I'd imagine we have to modify our web.config file ... but what and how? Here's what we've got under system.serviceModel in our web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"></serviceHostingEnvironment>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"></standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
So what do we need to do next?
Ok, so it's hard to be prescriptive without ALL of the code unfortunately, but here's the overview:
You'll want to add those bindings and behaviors into the web.config.
I'd start with a basicHttpBinding, and just make it work like it does currently, but this time you'll be specifying your binding details instead of using defaults. To "turn off" https, change the Security mode in the bindingConfiguration to None.
You'll have something like this for your WCF service when you are done:
<services>
<service behaviorConfiguration="webServiceClientBehavior" name="My.Service.ServiceName">
<endpoint address="http://localhost:5803/LSClient" binding="basicHttpBinding" bindingConfiguration="secureBinding" contract="My.Service.IServiceName"/>
</service>
</services>
For the bindingConfiguration:
<bindings>
<basicHttpBinding>
<binding name="secureBinding">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
For the behaviorConfiguration:
<serviceBehaviors>
<behavior name="webServiceClientBehavior">
<!--For MetaData-->
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:5802/LSClientMD"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
These will need to be adjusted slightly for your implementation, but that's a basic overview.

WCF 3.5 running SOAP and REST services side by side in IIS

I know that similar question was asked here :
Running SOAP and RESTful on the same URL
Hosting WCF soap and rest endpoints side by side
but didn't find an answer to my problem.
I have two custom servicehostfactories that enables Dependency Injection :
public class StructureMapSoapServiceHostFactory : ServiceHostFactory
public class StructureMapRestServiceHostFactory : WebServiceHost2Factory
The implementation details are not important here.
Then I definied two endpoints in web.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexGet">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<mexHttpBinding>
<binding name="mexHttpBinding" />
</mexHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="mexGet" name="ServiceImplementation.ServiceCategory">
<endpoint address="rest"
binding="webHttpBinding"
contract="Contracts.ServiceContracts.Mobile.IServiceCategory"
behaviorConfiguration ="jsonBehavior"/>
<endpoint address="soap"
binding="basicHttpBinding"
contract="Contracts.ServiceContracts.Mobile.IServiceCategory" />
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding" bindingConfiguration="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Then I created two .svc files for each custom host factories :
ServiceCategoryRest.svc
ServiceCategorySoap.svc
I don't like it. What I would like to do is to have URL in that style :
REST : http://server:port/rest/categories/{id} which mapps to the implementation of my ServiceCategory.GetCategory(int id)
SOAP : http://server:port/soap/GetCategory?id=someId
My questions are. Do i need different svc files to activate host services ? If I need there two .svc files, how can I achieve the URI above ? I'm afraid that I should configure IIS rewriting or something but would like to avoid that.
Thanks in advance for your help.
Thomas
You can achieve what you're looking for with service routes - part of ASP.NET routing, available from ASP.NET 3.5 SP1 on up.
Check out these resources:
RESTful WCF Services with No svc file and no config
Drop the Soap: WCF, REST, and Pretty URIs in .NET 4
making a WCF REST stand-alone service exe from scratch – part 1 of 4, creating the minimal bare service
Using Routes to Compose WCF WebHttp Services
In .NET 3.5 SP1, you need to add some extra infrastructure to your web.config (web routing module etc.) - while in .NET 4, this is all already built in.
After few searches I found out that in fact I don't need two different .svc files and two different ServiceHostFactories.
I kept only the StructureMapRestServiceHostFactory : WebServiceHost2Factory and ServiceCategoryRest.svc which handles well requests in REST mode and call in RPC-SOAP mode.
So if you want to run side by side the REST and the SOAP you can do it only with WebServiceHost2Factory.
If then you want to get rid of the .svc part from the URL, please read the Rick Strahl post west-wind.com/weblog/posts/570695.aspx.

Metadata request requires authentication in WCF even though service description page doesn't

I've set up a WCF service to require NTLM authentication using the following configuration:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="BinarySecurityBinding">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Ntlm"/>
</binding>
</customBinding>
</bindings>
<services>
<service name="Services.LogisticsServices" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="BinarySecurityBinding" contract="Services.ILogisticsServices" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I did this so that the applications that consume the web service are forced to log in because all my service's operations use impersonation ([OperationBehavior(Impersonation = ImpersonationOption.Required)]).
In IIS 7 I've enabled anonymous and Windows authentication.
When I visit http://test.server/LogisticsServices.svc, which hosts the service described above, I can see the default service description page anonymously. However, when Visual Studio tries to access http://test.server/LogisticsServices.svc/$metadata to generate a client proxy, the server is responding with HTTP code 401 and expecting authentication. Not only would I've expected the metadata to be available anonymously, but additionally, the server is not accepting the credentials I am giving it (even though, I know for a fact that they are correct).
Testing different configuration, I tried removing the authenticationScheme from my binding's transport, just to be able to generate the client proxy, but that results in an exception because the service's operations require impersonation ([OperationBehavior(Impersonation = ImpersonationOption.Required)]).
What am I missing in my service's configuration that would make the service's metadata available anonymously? I'm also open to suggestions if I'm approaching the whole thing wrong.
here is a similar discussion:
Getting an Security setting exception while accessing a WCF service
One way around this is not to use the autogenerated proxies.
In cases where we have control over both the server and the client we have found that it is much more productive to avoid using the autgenerated proxies.
A screencast of how to do this can be found here: http://www.dnrtv.com/default.aspx?showNum=122
You could try imperative instead of declarative model, see: http://msdn.microsoft.com/en-us/library/ms730088.aspx

WCF Error - Could not find a base address that matches scheme

I'm trying to get a WCF web service to work with SSL, as you can imagine it works on my machine, however when I run it on the production environments I get this instead:
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https].
Despite many hours of wrestling with this problem I still have very little idea what this error message actually means - googling for this error message finds loads of people saying that I should either specify an address in my endpoint configuration or add a base address to my service, however:
My service worked perfectly fine without specifying either with SSL disabled
In fact, my service works perfectly fine with SSL with the exact same configuration on another machine
Besides, I've found a post which reliably informs me that when hosting under IIS the base address is ignored anyway.
As you can probably tell, I'm currently feeling a very fustrated at my utter failure to achieve what I believed to be a relatively simple task, so:
What does this error message actually mean?
How are base addresses determined when hosting under IIS?
Where can I find reliable, understandable documentation about what all of my copy-pasted configuration actually means?
What do I need to do to get my service to actually work?
The interesting bits of my web.config are:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="MyService" behaviorConfiguration="MyBehavior">
<endpoint binding="basicHttpBinding" bindingConfiguration="SecureTransport"
bindingNamespace="http://MyNamespace/Service" name="Basic"
contract="MyContract" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="SecureTransport">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
One thing that is off field but can cause this message is if the SSL certificate on the server is expired or not set up correctly.