Issue with multiple interfaces in a single service - wcf

I am using WCF with NetTcpBinding on a solution where both client and server are windows forms. The service is hosted by one of them. I am using VS.2012.
On the server side I have several service contracts (related) all of which are implemented in a single service class. Like this:
public class MyService : IServiceA, IServiceB
{
}
and they should be accessible via net.tcp://localhost:4545/control/ which would lead to the following service addresses:
IServiceA (endpoint alphaEP) : net.tcp://localhost:4545/control/ASvc/
IServiceB (endpoint betaEP) : net.tcp://localhost:4545/control/BSvc/
And when I use svcutil.exe to generate the client stuff I see that it generates TWO service client classes, one for each interface, so when I use the ServiceBClient it generates an exception inidicating it could not find a 'betaEP' with contract 'IServiceB' even though the app.config has the same binding configuration and has both endpoints defined
<bindings>
<netTcpBinding>
<binding name="alphaEP">
<reliableSession enabled="true" />
<security mode="None" />
</binding>
<binding name="betaEP">
<reliableSession enabled="true" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
and this
<client>
<endpoint address="net.tcp://localhost:4545/control/ASvc"
binding="netTcpBinding" bindingConfiguration="alphaEP"
contract="CodeDom.IServiceA" name="alphaEP">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="net.tcp://localhost:4545/control/BSvc"
binding="netTcpBinding" bindingConfiguration="betaEP" contract="CodeDom.IServiceB"
name="betaEP">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
Why can't it find the endpoint if this client app.config was generated by svcutil.exe based on the server configuration?
Why does it generates two client classes instead of a single one? would that be the source of the problem? I have multiple related services to expose and I don't want to occupy more than one port on that. Do note, this is Net TCP Binding.

Related

more than one endpoint configuration for that contract was found

I have a question about my soap services(wcf)
I implement my wcf service and all the function implement correctly at compile time
I do not have any compile time error but when i run my code I received this error message
An endpoint configuration section for contract 'test.ICore' could not be loaded because more than one endpoint configuration for that contract was found. Please indicate the preferred endpoint configuration
I think in soap services we need some change in web.config file
another point is that my project have multiple soap services.
may it cause a problem?
how can i solve this issue?
thank you so much
I think your problem is because of you have a multiple endpoint with the same address in your web.config file
like that
<binding name="TestSoap">
<security mode="Transport" />
</binding>
<binding name="TestSoap" />
<endpoint address="http://TestSoap/Core.svc/soap"
binding="basicHttpBinding" bindingConfiguration="Soap" contract="TestSoap.ICore"
name="TestSoap" />
<endpoint address="https://TestSoap/Core.svc/soap"
binding="basicHttpBinding" bindingConfiguration="TestSoap"
contract="TestSoap.ICore" name="TestSoap" />
you can use this example for your code.
I hople you can solve your problem
In general, an interface contract can be supported by multiple endpoints, but bindings and addresses can vary, such as this:
Server-side:
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint address="secure"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
Client-side:
<client>
<endpoint name="basic"
address="http://localhost/servicemodelsamples/service.svc"
binding="basicHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpoint name="secure"
address="http://localhost/servicemodelsamples/service.svc/secure"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</client>
In the call:
CalculatorClient client = new CalculatorClient("basic");
Console.WriteLine("Communicate with basic endpoint.");
client = new CalculatorClient("secure");
Console.WriteLine("Communicate with secure endpoint.");
Feel free to contact me if have any issues.

Muliple Service Behaviors to same service in WCF

Can we attach multiple service behaviors to the same service in WCF.If yes how can we do that - via config file or as attributes?
Yes, you can.
ServiceEndpoint has a Behaviors collection.
So if you create a service in C# code, you may add any behavior to this collection: standard or your one. The example of how to create custom behavior and add it to the endpoint see here. Keep in mind that you can create and add as many behaviors as you need.
If you want to add behaviors in the configuration, you will need to create Behavior configuration extension. Here is an example hot to create it and add it to the endpoint in config file.
EDIT:
Service behaviors can be added in absolute same way
Yes you can.
You need to configure your behaviors and, in service tag, configure each behavior, like this:
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- First behavior:
http://localhost/servicemodelsamples/service.svc -->
<endpoint address=""
binding="basicHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- Second behavior, with secure endpoint exposed at {base address}/secure:
http://localhost/servicemodelsamples/service.svc/secure -->
<endpoint address="secure"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
</service>
The same service for ICalcular, for two different behaviors.
Read more here: https://msdn.microsoft.com/en-us/library/ms751515.aspx
Yes We can Create Multiple end points
<services>
<service name="ReportService.ReportService">
<endpoint
address="ReportService"
binding="netTcpBinding"
contract="ReportService.IReportService">
</endpoint>
<endpoint
address="ReportService"
binding="basicHttpBinding"
contract="ReportService.IReportService">
</endpoint>
</service>
</services>
we can create multiple end points like this.in client side app.config or webconfig file it show like this
<bindings>
<netTcpBinding>
<binding name="netTcpBinding_IReportService" />
</netTcpBinding>
<basicHttpBinding>
<binding name="basicHttpBinding_IReportService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="" binding="netTcpBinding"
bindingConfiguration="netTcpBinding_IReportService" contract="ServiceReference.IReportService"
name="netTcpBinding_IReportService">
</endpoint>
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="basicHttpBinding_IReportService" contract="ServiceReference.IReportService"
name="basicHttpBinding_IReportService">
</endpoint>
</client>
Then we should mention the binding name while we are referring
ServiceReference.ReportServiceClient client = new ServiceReference.ReportServiceClient(netTcpBinding_IReportService);
Now it will work with netTcpBinding

Is there a way to call 'Update Service Reference' without it changing the App.Config?

Ok, I manage my own App.Config. I don't need a wizard to do it for me, thank you very much. And the code that it puts in my App.Config is verbose garbage. I am capable of writing my own WCF endpoints and bindings. I just want Visual Studio 2010 to do what it is best at doing: code generation. Just give me the server and data-contract code! Is there any way to turn this off? Is there a way to call 'Update Service Reference' without VS changing the App.Config? Its very frustrating. Now it gives me an exception unless I completely delete all of the endpoint nodes from my App.Config.
This is the exception that I get:
There was an error downloading
'http://localhost:8732/MyService/mex'.
The request failed with HTTP status 400: Bad Request.
A child element named 'endpoint' with same key already exists at the
same configuration scope. Collection elements must be unique within
the same configuration scope (e.g. the same application.config file).
Duplicate key value:
'contractType:Web.DataService.MyService.IMyService;name:MyService.Live'.
(C:\ProjectPath\App.config line 152)
And here is my App.Config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="Binding.Debug" maxReceivedMessageSize="2147483647">
</binding>
<binding name="Binding.Secure" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<!-- Debug client endpoints -->
<endpoint name="MyService.Debug"
contract="Web.DataService.MyService.IMyService"
address="http://localhost:8732/MyService"
binding="wsHttpBinding"
bindingConfiguration="Binding.Debug"
/>
<endpoint name="MyService1.Debug"
contract="Web.DataService.MyService1.IMyService1"
address="http://localhost:8732/MyService1"
binding="wsHttpBinding"
bindingConfiguration="Binding.Debug"
/>
<endpoint name="MyService2.Debug"
contract="Web.DataService.MyService2.IMyService2"
address="http://localhost:8732/MyService2"
binding="wsHttpBinding"
bindingConfiguration="Binding.Debug"
/>
<endpoint name="MyService3.Debug"
contract="Web.DataService.MyService3.IMyService3"
address="http://localhost:8732/MyService3"
binding="wsHttpBinding"
bindingConfiguration="Binding.Debug"
/>
<!-- Local client endpoints -->
<endpoint name="MyService.Local"
contract="Web.DataService.MyService.IMyService"
address="https://www.mydomain.com/MyVirtualDirectory.Local/MyService.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService1.Local"
contract="Web.DataService.MyService1.IMyService1"
address="https://www.mydomain.com/MyVirtualDirectory.Local/MyService1.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService2.Local"
contract="Web.DataService.MyService2.IMyService2"
address="https://www.mydomain.com/MyVirtualDirectory.Local/MyService2.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService3.Local"
contract="Web.DataService.MyService3.IMyService3"
address="https://www.mydomain.com/MyVirtualDirectory.Local/MyService3.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<!-- Beta client endpoints -->
<endpoint name="MyService.Beta"
contract="Web.DataService.MyService.IMyService"
address="https://www.mydomain.com/MyVirtualDirectory.Beta/MyService.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService1.Beta"
contract="Web.DataService.MyService1.IMyService1"
address="https://www.mydomain.com/MyVirtualDirectory.Beta/MyService1.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService2.Beta"
contract="Web.DataService.MyService2.IMyService2"
address="https://www.mydomain.com/MyVirtualDirectory.Beta/MyService2.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService3.Beta"
contract="Web.DataService.MyService3.IMyService3"
address="https://www.mydomain.com/MyVirtualDirectory.Beta/MyService3.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<!-- Live client endpoints -->
<endpoint name="MyService.Live"
contract="Web.DataService.MyService.IMyService"
address="https://www.mydomain.com/MyVirtualDirectory/MyService.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService1.Live"
contract="Web.DataService.MyService1.IMyService1"
address="https://www.mydomain.com/MyVirtualDirectory/MyService1.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService2.Live"
contract="Web.DataService.MyService2.IMyService2"
address="https://www.mydomain.com/MyVirtualDirectory/MyService2.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
<endpoint name="MyService3.Live"
contract="Web.DataService.MyService3.IMyService3"
address="https://www.mydomain.com/MyVirtualDirectory/MyService3.svc"
binding="wsHttpBinding"
bindingConfiguration="Binding.Secure"
/>
</client>
</system.serviceModel>
This is very frustrating!
Edits:
I've figured out the exception that I was getting. I had MyService2.Live twice. I fixed this and no longer get the exception. I'd still like to know if I can keep VS10 from changing my App.Config.
You could use the svcutil tool to generate the files and manually merge them with the ones you have modified.
p.s: use slsvcutil if your client is Silverlight
My solutions for the problem ('Update service reference' takes 2 seconds ... svcutil with manual copy paste takes 30 seconds and too much alt-tabs):
If you're on source control (e.g. TFS) ... check in the app or web.config before updating. Then run 'Update service reference'. This will automatically check out the config file. After the update, just 'Undo checkout' from source control should put the original one back, but the generated reference code will be updated.
If not on source control: Open the app or web.config file, select all text (ctrl+a), copy (ctrl+c), update service reference, select all text in the config file again (ctrl+a), paste (ctrl+v).
It takes a few seconds longer, but still less of a hazard than using svcutil, which to be honest I only use when adding a service in the IDE fails and I need some info the dialog won't give me.
Sidenote: If you're adding a service, you should manually add the correct bindings and endpoints for your new service ofcourse.

Another - HTTP request is unauthorized error

Whenever I try to consume my web service through WCF, I receive this error:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLMnProviders'.
I know I have Kerberos setup correctly for this environment (it's calling SharePoint 3.0 services that I use in other applications). Integrated Windows security has been working great but this is the first time I've tried to consume it through WCF.
I've gone through this site many times to ensure I have the right header. Is the above error failing because it's expecting "Negotiate" but it's receiving "Negotiate,NTLMnProviders"? I know I can change my headers through that site but it always has 'Negotiate,NTLMnProviders' for the Kerberos header. Anyone got any ideas?
Not really an answer but here are some more details...
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ListsSoap">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows"/>
</security>
</binding>
<binding name="SiteDataSoap">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://something.com/_vti_bin/lists.asmx"
binding="basicHttpBinding" bindingConfiguration="ListsSoap"
contract="WSS_Server.ListsSoap" name="ListsSoap">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="http://something.com/_vti_bin/SiteData.asmx"
binding="basicHttpBinding" bindingConfiguration="SiteDataSoap"
contract="WSS_Server_SiteData.SiteDataSoap" name="SiteDataSoap">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
And then I'm instantiating my proxy and calling this in code...
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
proxy.ClientCredentials.Windows.AllowNtlm = false;
// Web service call
proxy.GetWeb(...);

WCF: Could not find default endpoint element that references contract 'IService' in the ServiceModel client configuration section. when hosting in IIS

I have a WCF service which is being hosted in IIS. I have a WCF client also (a console application). I have used svcutil to build the proxy class and configuration file and then added those to my client project. It built properly. But when I tried to run the program, it is throwing the below exception
Could not find default endpoint element that references contract 'IService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
//My client program code
namespace MyFirstWCFClient
{
class Program
{
static void Main(string[] args)
{
ServiceClient objClient = new ServiceClient();
Console.WriteLine("Client calling the service....");
string strName=Console.ReadLine();
Console.WriteLine(objClient.HelloWorld("Shyju"));
Console.Read();
}
}
}
Output.config file of my client is
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/IISHostedserviceTest/Service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
contract="IService" name="WSHttpBinding_IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
and in the web.config of my service has the below configuration
<system.serviceModel>
<services>
<service name="Service" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="http://localhost/IISHostedserviceTest/Service.svc" binding="wsHttpBinding" contract="IService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I used this(http://www.wcftutorial.net/WCF-IIS-Hosting.aspx) tutorial to have a try on WCF.
Can anyone guide me how to resolve this ?
Quick question: if your client app is called myclient.exe, is your config in the same directory as the EXE and called MyClient.exe.config ?
You can't just take the output.config from svcutil - you will need to either add a app.config to your client console project (which will be renamed to myclient.exe.config when compiling), or you need to copy/rename the output.config to myclient.exe.config in order for your client app to find and use it.
You have to use the constructor for the client that specifies the endpoint configuration name, eg.
objClient = new ServiceClient ("WSHttpBinding_IService");
That will tell the proxy to use the configuration you specified in the config file.
I had a similar problem with 2 WCF services connecting one to another.
After generating output.config + MyService.cs class files with the svcutil.exe and copying them to the solution dir I had the same problem.
Just found an answer to this problem: You have to copy whole "bindings" tag to your main config file inside "ServiceModel" tag AND copy your referenced endpoint next to existing endpoints in your main config file - that solved the exception problem for me
Another approach to take would be to add a Service Reference to your IIS hosted service. Visual Studio will automatically run svcutil in the background and do the configuration work for you - i.e. it'll create the app.config for you.
Doing it manually is fine, but I suggest running it at least once by adding a Service Reference just to see it work properly.