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

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.

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.

WCF A call to SSPI failed, 'the target principal name is incorrect'

I'm getting this dreaded message and have spent a fair bit of time reading about it but have still been unable to solve it
I have a console app running on my client trying to invoke a WCF service on a different machine. The service is running under a domain account. I believe under this scenario it tries to authenticate using Kerberos
I have also read that if you supply a dummy serviceprincipalname on the client
<servicePrincipalName value="MySystem/Service1"/>
then it will fall back to using ntml.
I have tried this without luck. If the client is on the same machine as the service then it works fine. Not sure what else I can try. Here is the config on my client
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_HelpersService" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://myserver/SPInterface/HelpersService.svc/TCP" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_HelpersService"
contract="HelpersService" name="NetTcpBinding_HelpersService">
<identity>
<servicePrincipalName value="MySystem/Service1"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
What I also don't understand is that if I use the WCFTestClient in Visual Studio which generates the same config file from my local machine it works fine
My server config files has this in it:-
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="HelpersService.svc" service="SPInterface.Models.HelpersService" factory="SPInterface.WebService.HelpersServiceHostFactory"/>
</serviceActivations>
</serviceHostingEnvironment>
<services>
<service name="SPInterface.Models.HelpersService" behaviorConfiguration="Debug">
<endpoint address="TCP" binding="netTcpBinding" bindingNamespace="http://Server/SPInterface/Services" contract="SPInterface.Contracts.IHelpersService"/>
<endpoint address="Rest" binding="webHttpBinding" bindingNamespace="http://Server/SPInterface/Services" contract="SPInterface.Contracts.IHelpersService" behaviorConfiguration="Rest"/>
</service>
</services>
</system.serviceModel>
The inner exception is "the target principal name is incorrect"

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

Issue with multiple interfaces in a single service

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.

WCF maxReceivedMessageSize not being read from config

I have a the following server side app.config for a WCF service:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="default" maxReceivedMessageSize="5000000">
<readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="Core.TOAService.Service1Behavior"
name="Core.TOAService.TOAService">
<endpoint address="" binding="wsHttpBinding" contract="Core.TOAService.ITOAService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/Core.TOAService/TOAService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Core.TOAService.Service1Behavior">
<!-- 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="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
When I try and pass this service a largish file (only ~250KB), I get an exception logged in the svclog file:
The maximum message size quota for
incoming messages (65536) has been
exceeded. To increase the quota, use
the MaxReceivedMessageSize property on
the appropriate binding element.
As you can see from the binding section at the top of the config, I have tried to set the maxReceivedMessageSize to 5000000 but the service still thinks it is set to the default 65536. Any ideas as to what is wrong or which is the "appropriate" binding element?
There's more settings :-) Try "maxBufferPoolSize" and "maxBufferSize" on the <binding> tag.
But the biggest problem is: your endpoint does not reference that binding configuration!
<endpoint address=""
binding="wsHttpBinding" contract="Core.TOAService.ITOAService">
You need to add a reference to it so that it gets useful - just calling it "default" doesn't work.....
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="default"
contract="Core.TOAService.ITOAService">
You're ahead of your times ;-) In WCF 4 (with .NET 4.0 - sometime later this year 2009), you'll be able to define "default binding configurations" without having to explicitly name and reference them - but for now, you need to create a link between your endpoint and its binding and any binding (or behavior) configuration you have!
Marc
If you're still getting this error message while using the WCF Test Client, it's because the client has a separate MaxBufferSize setting.
To correct the issue:
Right-Click on the Config File node at the bottom of the tree
Select Edit with SvcConfigEditor
A list of editable settings will appear, including MaxBufferSize.
Note: Auto-generated proxy clients also set MaxBufferSize to 65536 by default.
There are several places that you need to set the size. In your case I think that you need to add read quotas. Here is an example:
<basicHttpBinding>
<binding name="httpBasicBinding_Service" closeTimeout="00:03:00"
openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00"
maxBufferSize="2000001"
maxBufferPoolSize="2000001" maxReceivedMessageSize="2000001">
<readerQuotas maxDepth="2000001" maxStringContentLength="2000001"
maxArrayLength="2000001" maxBytesPerRead="2000001" maxNameTableCharCount="2000001" />
</binding>
</basicHttpBinding>