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
Related
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.
suppose my wcf has many end point with different binding.so when user / client add service ref from VS IDE at then multiple endpoint related data expose & added in client config file at client side.
Can we design service in such a way as a result only one endpoint related address will be revealed at client side?
Suppose I have one service with HTTP & TCP related endpoint and I want when external customer will add our service from their VS IDE then they will see our HTTP endpoint address not TCP. So guide me how could I do this? How to design service end config file for my requirement?
here i am attaching a small sample code for multiple endpoint related in config file.
<services>
<service behaviorConfiguration="MulContractService" name="MyWCFLibrary.MultipleContract">
<clear />
<endpoint binding="basicHttpBinding" bindingConfiguration="MulContractBasicBinding"
name="MulContractBasicEndPoint" contract="MyWCFLibrary.IMultipleContract"
listenUriMode="Explicit">
<identity>
<dns value="localhost" />
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<endpoint address="test1" binding="wsHttpBinding" bindingConfiguration="MulContractWsHttpBinding"
name="MulContractWsHttp" contract="MyWCFLibrary.IByeWorld"
listenUriMode="Explicit">
<identity>
<dns value="localhost" />
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<endpoint address="test1" binding="wsHttpBinding" bindingConfiguration="MulContractWsHttpBinding"
name="MulContractWsHttp" contract="MyWCFLibrary.IHelloWorld"
listenUriMode="Explicit">
<identity>
<dns value="localhost" />
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<endpoint address="net.tcp://localhost:8733/Design_Time_Addresses/MyWCFLibrary/MultipleContract/"
binding="netTcpBinding" bindingConfiguration="MulContractTCPBinding"
name="MulContractTCPEndPoint" contract="MyWCFLibrary.IMultipleContract" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MyWCFLibrary/MultipleContract/" />
</baseAddresses>
</host>
</service>
</services>
EDIT
here i am giving my new full code and just guide me does it work?
namespace CustomService
{
[ServiceContract]
public interface IEmp
{
[OperationContract]
string GetEmp();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class BusinessLayer : IEmp
{
public BusinessLayer()
{
}
public string GetEmp()
{
return "Casino";
}
}
}
Config code at service end
<services>
<service name="CustomService.BusinessLayer">
<endpoint address="CustomerFactory" binding="basicHttpBinding"
bindingConfiguration="HTTPBindingConfig" name="CustomerFactoryHTTP"
contract="CustomService.IEmp" listenUriMode="Explicit" />
</service>
<service name="CustomService.BusinessLayer">
<endpoint binding="basicHttpBinding" bindingConfiguration="HTTPBindingConfig"
name="CustomerMasterHTTP2" bindingName="CustomerMaster" contract="CustomService.IEmp" />
</service>
</services>
just tell me the above config will work?
in the above config i define two service tag with same name because my service full name with namespace is CustomService.BusinessLayer
is it ok or do i need to give unique name for each service tag?
my intention is i will have same service but with multiple service tag and when customer will add my service ref at their end then they will not be able to see all the endpoint.
my intention is not expose all endpoint & address to every client.
so guide me what i have done does it work or not....if not then rectify my config entry and tell me how could i restrict my endpoint not to expose each binding & address before all client. thanks
Maybe not what you are looking for but you could easily add another service to your project and give it the endpoints you want your client to see. Then the existing service could be just for TCP or for both types. Under the covers of course both services would run the same code.
Adding a service is just like adding any other file, right click, add New Item, WCF service. Then you can use the WCF configuration Editor to configure it if you dont want to do it by hand.
For what it is worth here is a config with two services. You can see that the first service has two endpoints, an Http and a TCP while the second service exposes just the http endpoint. Your two services would then each implement IService and would delegate to a common class or library.
<services>
<service name="Mynamespace.Service1">
<endpoint binding="basicHttpBinding"
bindingConfiguration="HTTPBindingConfig" name="MyserviceHTTP"
contract="Mynamespace.IService" listenUriMode="Explicit">
</endpoint>
<endpoint binding="netTcpBinding"
bindingConfiguration="TCPSecured" name="MyserviceHTTP"
contract="Mynamespace.IService" />
</service>
<service name="Mynamespace.Service2">
<endpoint binding="basicHttpBinding"
bindingConfiguration="HTTPBindingConfig" name="MyserviceHTTP"
contract="Mynamespace.IService" listenUriMode="Explicit">
</endpoint>
</service>
</services>
I have very specific question..
If i create one WCF Service and it has multiple endpoints with the name how can i access that using browser ?
Also How can i access that in my client application via Add Service Reference ?
like my config code:
<services>
<service name="MultipleEndpoint.SampleService" behaviorConfiguration="MultipleEndpoint.SampleService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:55052/SampleService.svc"/>
</baseAddresses>
</host>
<endpoint address="/basic" binding="basicHttpBinding" contract="MultipleEndpoint.ISampleService" bindingConfiguration="basicBinding" >
</endpoint>
<endpoint address="/wsHttp" binding="wsHttpBinding" contract="MultipleEndpoint.ISampleService" bindingConfiguration="wsBinding" >
</endpoint>
<endpoint address="/webHttp" binding="webHttpBinding" contract="MultipleEndpoint.ISampleService" behaviorConfiguration="REST">
</endpoint>
</service>
</services>
Now, when i tried to access that using
http://localhost:55052/SampleService.svc/basic or
http://localhost:55052/SampleService.svc/wsHttp
it gives me page/ resource not found IE Standard Error Message...
Same time i like to know how would i add this type of url as a service reference in my client application ?
Those service addresses are different and they are not strictly needs to be brow-sable, means you can't browse a service for an endpoint like http://localhost:55052/SampleService.svc/basic. Those addresses are used to distinguish endpoints in communication.
If you see the wsdl of the service all the addresses of those endpoints are specified there.
If you create the proxy of the service through "Add Service Reference" all the endpoints are created in the configuration separately like..
<client>
<endpoint address="http://localhost:54671/Service1.svc/basic"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
<endpoint address="http://localhost:54671/Service1.svc/ws" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1">
</endpoint>
...
</client>
Say if you want to talk to the service using the basic http endpoint then you can create the proxy for that by passing the corresponding endpoint configuration name in the ctor.
Ex.
// this will uses the basic http endpoint.
Service1Client client = new Service1Client("BasicHttpBinding_IService1");
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.
I am using CSLA.NET. It works realy nice with the wsHttpBinding. Now, I have my own Windows-Service and search the solution, that I can use this Windows-Service as the CSLA-Server and using nettcpbinding. Can someone give me a tip how to going on? Perhaps someone has a sample how I can do that.
Thank you!
Best Regards, Thomas
Basically, you need to do two things:
change your server-side configuration to include an endpoint with the netTcpBinding (this can be in addition to the existing wsHttpBinding endpoint - no problem)
add the netTcpBinding to your client's config file as well and selecting that endpoint when you connect
You should have something like this in your server side config:
<services>
<service name="YourService">
<endpoint name="something"
address=""
binding="wsHttpBinding"
contract="IYourService" />
</service>
</services>
Just add an endpoint for the netTcpBinding:
<services>
<service name="YourService">
<endpoint name="something"
address=""
binding="wsHttpBinding"
contract="IYourService" />
<endpoint name="something"
address="net.tcp://YourServer:7171/YourService"
binding="netTcpBinding"
contract="IYourService" />
</service>
</services>
Now if you're hosting in IIS, you might run into some problems - you need to configure IIS7 (Win2008 or Win2008R2 server), and in IIS6, you won't be able to host your netTcp service in IIS6 :-(
Same thing on the client side - add a second endpoint for netTcp:
<client>
<endpoint name="something"
address="http://YourServer/SomeVirtDir/YourServiceFile.svc"
binding="wsHttpBinding"
contract="IYourService" />
<endpoint name="netTcpEndpoint"
address="net.tcp://YourServer:7171/YourService"
binding="netTcpBinding"
contract="IYourService" />
</client>
and now when you create your endpoint in code, use the named endpoint:
YourServiceClient client = new YourServiceClient("netTcpEndpoint");
That should be all, really (unless CSLA requires something extra which I wouldn't know about.... I know "plain-vanilla" WCF)