Construct Solution with Multiple WCF Applications - c#

We currently have a solution with only one WCF application, during the next two years the solution grows a lot.
It's around 70 different services.
We are using Windows Identity Foundation for security for majority, others use SSL and some don't have
I'm looking to restructure the application, I'am thinking about having multiple WCF application (one for business services, and other for backend services, etc...),
I think it can help for a lot for testing.
My question is:
Is there a way to construct a solution with multiple WCF applications without having to create and deploy multiple packages (not very usefull for deployments)
If I restucture the application, I will have 4 or 5 different services projects and also need an app.config file for each(not easy to maintain or upgrade in production environments)

You can have as many service assemblies in a WCF host as you like just make sure they have unique names. Every service dll gets its own project and the host stays at one project in the solution. Then create an app.config like this:
<services>
<service behaviorConfiguration="serviceBehaviour" name="DLSService.DLSService">
<endpoint address="DLSService" binding="basicHttpBinding" bindingConfiguration=""
name="basicHttpDLS" contract="DLSService.IDLSService" />
<endpoint binding="mexHttpBinding" bindingConfiguration="" name="mexDLS"
contract="IMetadataExchange" />
<endpoint address="DLSService" binding="netTcpBinding" bindingConfiguration=""
name="netTcpDLS" contract="DLSService.IDLSService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServicesHost/DLSService" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="serviceBehaviour" name="RopsPreorderService.RopsPreorderService">
<endpoint address="RopsPreorderService" binding="basicHttpBinding" bindingConfiguration=""
name="basicHttpPreorderService" contract="PreorderService.IPreorderService" />
<endpoint binding="mexHttpBinding" bindingConfiguration="" name="mexRopsPreorderService"
contract="IMetadataExchange" />
<endpoint address="PreorderService" binding="netTcpBinding" bindingConfiguration=""
name="netTcpPreorderService" contract="RopsPreorderService.IPreorderService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServicesHost/PreorderService" />
<add baseAddress="net.tcp://localhost:9000/PreorderService" />
</baseAddresses>
</host>
</service>
</services>

Related

Why I can't find the certificate in a WCF Service?

I'm trying to develop a service with WCF but I can't find the certificate that I created, this certificate is located under TrustedPeple folder. So far this is my chunk of code that I wrote:
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySubjectName,
"WCfClient");
As you can see from the above code, I also tried to manually set the certificate characteristics but I still can't find it.
Also I'll post a portion of my conif xml file for a better understanding:
<services>
<service
name="XMLServices.CriDecServices.CriDecService"
behaviorConfiguration="wsHttpCertificateBehavior">
<endpoint name="CriDecPoint"
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
contract="XMLContracts.ServiceContracts.ICriDecService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/XMLServices/CriDecServices/CriDecService" />
</baseAddresses>
</host>
</service>
<service
name="XMLServices.UtenteServices.UtenteService"
behaviorConfiguration="wsHttpCertificateBehavior">
<endpoint
name="UserPoint"
address=""
binding="wsHttpBinding"
bindingConfiguration="wsHttpEndpointBinding"
contract="XMLContracts.ServiceContracts.IUtenteService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8766/XMLServices/UtenteServices/UtenteService" />
</baseAddresses>
</host>
</service>
</services>
This is the exception that I get:
"Client certificate not given. Specify a client certificate in ClientCredentials."
Can anyone help me out to understand why I can't seem to find my certificate? Thanks
If you look here you'll see that the store you are trying to use isn't the one from the trusted people folder but the one from the personal folder
you should use
StoreName.TrustedPeople
look here for more details https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.storename(v=vs.110).asp
also most likely you need StoreLocation.LocalMachine.

Service metadata may not be accessible

I am trying to run my project.I am getting this error "Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata".
add this endpoint to your application.config file:
<services>
<service .....>
<endpoint binding="mexHttpBinding" bindingConfiguration="" name="mexService" contract="IMetadataExchange" />
<endpoint ...... the usual endpoints />
</service>
</services>

WCF HTTP and NamedPipe service

I'm creating a WCF service which, at the moment, exposing a number of contracts using a basicHttpBinding. However, I now want to use the service locally on the same machine, and a netNamedPipeBinding seems more appropriate in terms of performance. For that reason, I want to expose the service using a named pipe and HTTP.
At the moment I'm doing this with the following configuration:
<service name="WCFService.MyService" behaviorConfiguration="serviceBehaviour">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MyService" />
<add baseAddress="net.pipe://localhost/MyService" />
</baseAddresses>
</host>
<endpoint address="calculator" binding="basicHttpBinding" contract="WCFService.ICalculatorService" />
<endpoint address="database" binding="basicHttpBinding" contract="WCFService.IDatabaseService" />
</service>
This appears to work fine, but on closer inspection the endpoints are still using the basicHttpBinding. This works, but I get the impression it's creating unnecessary overhead.
Do I need to create an endpoint for each contract, and each binding type (i.e. basicHttpBinding and netNamedPipeBinding) or am I going about this completely wrong?
(If it's not clear, I'm fairly new to WCF!)
Yes, you need to specify multiple endpoints (1 endpoint per binding):
<endpoint address="calculator" binding="basicHttpBinding" contract="WCFService.ICalculatorService" />
<endpoint address="database" binding="basicHttpBinding" contract="WCFService.IDatabaseService" />
<endpoint address="calculator" binding="netNamedPipeBinding" contract="WCFService.ICalculatorService" />
<endpoint address="database" binding="netNamedPipeBinding" contract="WCFService.IDatabaseService" />

Multiple contracts with same bindings..How?

How do I use multiple contracts with the same binding on the same port through C# code?
Would appreciate any simple code snipplet...
Thanks so much
What about this:
public class Service : IServiceContract1, IServiceContract2
{
...
}
Configuration (can be easily rewritten to code if you add Endpoint instances to ServiceHost by calling AddServiceEndpoint)
<services>
<service name="Service">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8888/Service" />
</baseAddresses>
</host>
<endpoint address="first" binding="basicHttpBinding" contract="IServiceContract1" />
<endpoint address="second" binding="basicHttpBinding" contract="IServiceContract2" />
</service>
</services>
I'm afraid there is no "simple code snippet" for this. Use the following article to get started and just add more ServiceHost objects: http://msdn.microsoft.com/en-us/library/ms733069.aspx
If you haven't already, it would be wise to get a book on WCF.

Indexing ServiceEndpointElementCollection

In the following config file excerpt, the WCF service has two endpoints.
<service behaviorConfiguration="AtomTcpHub.Behavior"
name="AtomTcpHub.HubTcp">
<endpoint address="" binding="netTcpBinding"
name="AtomHubEndpoint" contract="AtomLib.IAtomPublisher">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
name="" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/AtomTcpHub/" />
<add baseAddress="net.tcp://dv-pw/AtomTcpHub/" />
</baseAddresses>
</host>
</service>
In my code there is discovery logic, which responds to a UDP request by replying with the connection Uri for the WCF service. Obtaining a collection of endpoints is straightforward.
System.Configuration.Configuration config = System.Configuration
.ConfigurationManager
.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
ServicesSection section = config.SectionGroups["system.serviceModel"]
.Sections["services"] as ServicesSection;
ServiceEndpointElementCollection seec =
section.Services["AtomTcpHub.HubTcp"].Endpoints;
The problem is extracting the ServiceEndpointElement. We can have it by index:
ServiceEndpointElement see = seec[0];
but this is brittle; if the order of nodes changes it will break. Visual Studio tells me there is another indexer permitting an object value, but there is no further indication. Experimentation tells me that it isn't the value of the name attribute.
The following code works, but it's just hideous.
string serviceEndpointUri;
foreach(ServiceEndpointElement serviceEndpointElement in seec)
if (serviceEndpointElement.Name == "AtomHubEndpoint")
{
_serviceEndpointUri = serviceEndpointElement.Address.AbsoluteUri;
break;
}
Is there a more direct or more elegant way to do this?
You could always use some Linq to accomplish this, to simply shorten things a bit.
ServiceEndpointElement element =
seec.OfType<ServiceEndpointElement>()
.FirstOrDefault(s => s.Name == "AtomHubEndpoint");

Categories