two endpoint within one service host - wcf

I have 3 projects in a solution as following:
WCF Service Library "ServiceLib"(contract ICalculator and its implementation Calculator1).
Console Application "ServiceHost" to host WCF Service Library(and another ICalculator implementation Calculator2);
add Calculator1 & Calculator2 into an instance of ServiceHost using method AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "Calculator1"),
AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "Calculator2")
Add Service Reference to "ServiceHost" to my client application(type of Console Application);
an app.config(auto-generated) within this project
question is: How to consume these two Calculators(different logic) from client app side, does it necessary to create two different types of client proxy or other way to do that?
thanks for your hand!
<endpoint address="http://localhost:8000/Calculator" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator" contract="Services_BaseAddress.ICalculator"
name="WSHttpBinding_ICalculator">
</endpoint>
<endpoint address="http://localhost:8000/DoubleCalculator" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator1" contract="Services_BaseAddress.ICalculator"
name="WSHttpBinding_ICalculator1">
</endpoint>

Related

Asp.NET Core 2.2 WCF Warning: Policy

I'm trying to add wsdl using WCF. But at first I get an warning like this;
enter image description here
Here is the details:
The following Policy Assertions were not Imported:
XPath://wsdl:definitions[#targetNamespace='urn:sap-com:document:sap:soap:functions:mc-style']/wsdl:binding[#name='zz_binding_SOAP12']
Assertions:
<saptrnbnd:OptimizedXMLTransfer xmlns:saptrnbnd='http://www.sap.com/webas/710/soap/features/transportbinding/'>..</saptrnbnd:OptimizedXMLTransfer>
<sapattahnd:Enabled xmlns:sapattahnd='http://www.sap.com/710/features/attachment/'>..</sapattahnd:Enabled>
The following Policy Assertions were not Imported:
XPath://wsdl:definitions[#targetNamespace='urn:sap-com:document:sap:soap:functions:mc-style']/wsdl:binding[#name='zz_binding']
Assertions:
<saptrnbnd:OptimizedXMLTransfer xmlns:saptrnbnd='http://www.sap.com/webas/710/soap/features/transportbinding/'>..</saptrnbnd:OptimizedXMLTransfer>
<sapattahnd:Enabled xmlns:sapattahnd='http://www.sap.com/710/features/attachment/'>..</sapattahnd:Enabled>
The optional WSDL extension element 'Policy' from namespace 'http://schemas.xmlsoap.org/ws/2004/09/policy' was not handled.
XPath: //wsdl:definitions[#targetNamespace='urn:sap-com:document:sap:soap:functions:mc-style']/wsdl:portType[#name='zz_test_web_structure']/wsdl:operation[#name='ZzTestWebService']
The optional WSDL extension element 'Policy' from namespace 'http://schemas.xmlsoap.org/ws/2004/09/policy' was not handled.
XPath: //wsdl:definitions[#targetNamespace='urn:sap-com:document:sap:soap:functions:mc-style']/wsdl:portType[#name='zz_test_web_structure']
I still can't run the wcf service after adding it. Does anyone know about this?
Microsoft WCF Web Service Reference Provider tool based on the Mex service endpoint, namely metadata exchange service endpoint instead of the Web service definition language(WSDL page).
<services>
<service name="WcfService1.Service1">
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
Or,
Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
If you prefer to generate a client proxy class by using WSDL, you could try the SVCUtil.exe tool.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/servicemodel-metadata-utility-tool-svcutil-exe
All the above ways can generate a client proxy class.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client
Besides, In WCF4.5 there is a new feature called SingleWSDL, which contains the whole WSDL with the related schema. It could be consumed perfectly by a third-party system.
What is the difference between ?wsdl and ?singleWsdl parameters
https://learn.microsoft.com/en-us/dotnet/framework/wcf/whats-new
Feel free to let me know if there is anything I can help with.

How can I programmatically create an endpoint and use it in my service instead of obtain it from the web.config?

Basically I want to create this binding that will listen to azure service bus queue:
<services>
<service name="myServiceName">
<endpoint address="sb://****.servicebus.windows.net"
listenUri="sb://****.servicebus.windows.net"
binding="netMessagingBinding"
bindingConfiguration="netMessagingBinding"
behaviorConfiguration="myConfiguration"
name="myServiceEndpoint"
contract="****" />
</service>
I also need to know how I can use it in my service.
Look at your servicehost file (.SVC) it can contain a reference to the factory class that generates your service file. More info here: http://msdn.microsoft.com/en-us/library/aa967286.aspx
By providing your own factory you get an ability to override the generation of your service class via CreateServiceHost method. That will give you more control as to how your service class is created. You can inject your own URL's,l etc.
HTH

WCF service versioning with single SVC

Due to some certain requirement, I've got to use a single svc for multiple service versions. I've separated the interface contract for each version using different namespaces. I have only one class (partial) implementing all the service versions.
My code is as below:
namespace Application.V1
{
[ServiceContract(Namespace = "http://google.com/ApplicationService/v1.0", Name = "IMathService")]
public interface IMathService
}
namespace Application.V2
{
[ServiceContract(Namespace = "http://google.com/ApplicationService/v2.0", Name = "IMathService")]
public interface IMathService
}
The Application/MathServiceV1.cs file:
public partial class MathService : V1.IMathService { }
The Application/MathServiceV2.cs file:
public partial class MathService : V2.IMathService { }
The Application/MathService.cs file:
public partial class MathService {}
I've added the following in the service web.config:
<service behaviorConfiguration="ServiceBehavior" name="Application.MathService">
<endpoint address="V1" binding="wsHttpBinding" contract="Application.V1.IMathService" />
<endpoint address="V2" binding="wsHttpBinding" contract="Application.V2.IMathService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
I have a file MathService.svc with the following:
<%# ServiceHost Service="Application.MathService, Application"
Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"%>
If I generate a proxy with the address http://localhost:8000/MathService.svc the client endpoints are generated as below:
<client>
<endpoint address="http://localhost:8000/MathService.svc/V1"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMathService"
contract="MathService.IMathService" name="WSHttpBinding_IMathService">
</endpoint>
<endpoint address="http://localhost:8000/MathService.svc/V2"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMathService1"
contract="MathService.IMathService1" name="WSHttpBinding_IMathService1">
</endpoint>
</client>
My concern is that the client endpoint address is generated with MathService.svc/V1 but I'd like to see V1/MathService.svc.
If i browse the service with the address http://localhost:8000/MathService.svc/V1 i am getting HTTP 400 Bad Request error.
Any suggestions?
Regarding your 400 bad request error - you probably dont have MEX enabled, so making a request without a payload makes no sense to the service.
Here is a question about enabling MEX:
WCF How to enable metadata?
Either enable MEX - or use a proper service consumer to call your service.
Regarding your addressing - you cannot do what you want to do with WCF alone. Because you are using IIS hosted WCF (I assume this because you are using an SVC file), your HTTP request must be directed to the location of your SVC file, and anything after that (/V1 for example) is used to locate the appropriate endpoint. This is just how it works in IIS. Putting the /v1/ BEFORE the file name (MathService.asmx) tells IIS to look for a folder called /v1/ before attempting to locate a file named MathService.asmx - obviously it wont find anything there!
However, you may be able to install a URL rewriter in your Web.config to redirect your preferred URI to the one mentioned above.
Here is some documentation on Url rewriting in asp.net:
http://www.iis.net/learn/extensions/url-rewrite-module/iis-url-rewriting-and-aspnet-routing

Using 2 WCF interfaces in the same svc file

We are trying to communicate with an external WCF service.
The WCF services are exposed via svc files. It appears that there are 2 interfaces exposed via the same svc file.
How can we configure this in the web.config file?
If I understand your question correctly, you have a single class that implements 2 WCF service contracts. In your web.config, you configure an endpoint for each service contract, but under the same <service> node. I've only done this when self-hosting WCF services, not in IIS, but I think if you specify a value for address in your endpoint configuration, it will make it relative to the location of the .svc file:
<service name="YourServiceLibrary.YourServiceClass">
<endpoint address="Service1"
contract="YourServiceLibrary.IService1"
...
/>
<endpoint address="Service2"
contract="YourServiceLibrary.IService2"
...
/>
</service>
You would then setup your client proxies for each service contract to point to http://YourServer/YourServicePath/YourServiceClass.svc/Service1 and http://YourServer/YourServicePath/YourServiceClass.svc/Service2

WCF client config: centralized endpoint address

i've a WCF client wicht refers to multiple services hosted in the same machine. like this example
<client>
<endpoint address="net.tcp://localhost:8731/TrackingService" binding="netTcpBinding" ...
</endpoint>
<endpoint address="net.tcp://localhost:8731/CommonService" binding="netTcpBinding"...
</endpoint>
</client>
is it possible to modify my app.config in order to keep the
net.tcp://localhost:8731
part of endpoint address in a different variable, so when i'll deploy i have to change it once?
Maybe a programmatically clever way to do this? My only need is to change "address:port".
Thank you in advance
No, unfortunately, on the client side, there's nothing like a <baseAddress> like on the server side, which you can set globally.
Each endpoint declaration must have the entire, complete URL in it, I'm afraid.
Marc
You can always programmatically create your client and read the address from a normal appconfig value. Like this
MyClient client=
new MyClient(new BasicHttpBinding(), new EndpointAddress(ConfigurationManager.AppSettings.Get("ServiceAddress");)