Programmatically define the Endpoint and Binding - c#

Warping the call of a web service in a Class Library, I had to past the endpoint definition from app.config to other project that was using the Library.
In order to get rid of that I try to translate my app.config setting into explicit in order to pass Binding and Endpoint definition to the ClientBase.
var client = new myServiceClient(customBinding, custonEndpoint);
I'm looking for a way to translate system.serviceModel definition into code.
And the simpliest definition is giving me issue. For example with the following configuration:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_MyService" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://address:port/Foo/Services/MyService"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_MyService"
contract="MyService.MyService" name="NetTcpBinding_MyService">
<identity>
<userPrincipalName value="FooBar#SecondLevel.TopLevel" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I find no property that match those parameter in NetTcpBinding neither in the Security property:
var endPoint = new EndpointAddress(__EndPoint);
var binding = new NetTcpBinding();
binding.Name = "";
Resulting in an error SSPI.

Related

Self Hosting WCF service using app.Config files

I have self hosting WCF service that contains it's own app.Config to expose endpoints required for the service contracts. If the service is started in the programs.cs main method it all works just fine and the metadata is exposed via the browser. However, I created a HostService class based on the ServiceBase class which in the same host library and is instantiated within the program.cs file. The HostService class starts the service and has a timer method to ping other client web services for information.
My question is, when I created the HostService : ServiceBase class and instantiate it from the main(), I have to put a duplicate app.Config file in the Service Library in order for the endpoints to properly exposed and return the metadata/wsdl. I don't want to maintain 2 duplicate app.config files if possible. Currently the host library and service library both require one. Is there a way to only have just one w/ the host that could be used for both? Sorry for the dumb question, but I'm new to WCF =)
Program.cs
static void Main(string[] args){
var service = new HostService();
service.StartHostService(args);
}
HostService.cs
public partial class HostService : ServiceBase
{
internal void StartHostService(string[] args)
{
this.OnStart(args);
Console.ReadLine();
this.OnStop();
}
....
}
Short answer is no. There must be two configs, one for the client that consumes the WCF and one for the server that exposes that communication methods with the WCF.
In order for your client to work, your config must be set with Client Configuration
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
<endpoint
name="endpoint1"
address="http://localhost/ServiceModelSamples/service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IHello"
behaviorConfiguration="IHello_Behavior"
contract="IHello" >
<metadata>
<wsdlImporters>
<extension
type="Microsoft.ServiceModel.Samples.WsdlDocumentationImporter, WsdlDocumentation"/>
</wsdlImporters>
</metadata>
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
// Add another endpoint by adding another <endpoint> element.
<endpoint
name="endpoint2">
//Configure another endpoint here.
</endpoint>
</client>
//The bindings section references by the bindingConfiguration endpoint attribute.
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHello"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard">
<readerQuotas maxDepth="32"/>
<reliableSession ordered="true"
enabled="false" />
<security mode="Message">
//Security settings go here.
</security>
</binding>
<binding name="Another Binding"
//Configure this binding here.
</binding>
</wsHttpBinding>
</bindings>
//The behavior section references by the behaviorConfiguration endpoint attribute.
<behaviors>
<endpointBehaviors>
<behavior name=" IHello_Behavior ">
<clientVia />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
notice the <client> tag specifying how the client must call the WCF.
and with Server Config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="myBindingConfiguration1" closeTimeout="00:01:00" />
<binding name="myBindingConfiguration2" closeTimeout="00:02:00" />
<binding closeTimeout="00:03:00" /> <!—- Default binding for basicHttpBinding -->
</basicHttpBinding>
</bindings>
<services>
<service name="MyNamespace.myServiceType">
<endpoint
address="myAddress" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration1"
contract="MyContract" />
<endpoint
address="myAddress2" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration2"
contract="MyContract" />
<endpoint
address="myAddress3" binding="basicHttpBinding"
contract="MyContract" />
</service>
</services>
</system.serviceModel>
</configuration>
Notice there is no <client> tag here.

C# SOAP WebService: HTTPS endpoint configuration

In a C# service i must add a Web Service reference for calling some metods.
The testing URL use an HTTPS protocol, so I'm try to edit my endpoint to call new address:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="fooSoap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://x.x.x.x/WS_Foo/Foo.asmx"
binding="basicHttpBinding" bindingConfiguration="fooSoap"
contract="WSFooReferences.fooSoap" name="fooSoap" />
</client>
</system.serviceModel>
And so, I'm trying to call my method in c#:
WSFooReferences.fooSoapClient fooWS = new WSFooReferences.fooSoapClient();
int iRetCode = fooWS.Ping("ID12345");
But I've this error:
The provided URI scheme 'http' is invalid; expected 'https'
How I can edit my endpoint configuration fot this case?
T'ks!

WCF exception--Faulted state

I added the WCF service reference to my project. Next step is to create a channel from the code.
WSHttpBinding bindingDialingType = new WSHttpBinding();
EndpointAddress endingPointDialingType = new EndpointAddress("http://wsvc.corporate.my.com/International/DialingService.svc");
ChannelFactory<IDialingService> iDialingServiceChannelFactory = new ChannelFactory<IDialingService>(bindingDialingType, endingPointDialingType);
IDialingService instanceIDialingService = iDialingServiceChannelFactory.CreateChannel();
Because I met an exception, so I guess that something wrong with my channel factory code.
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
To capture the exception, I had the code.
My app.config is:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_iLuCRE" />
</basicHttpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IDialingService">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://wsvc.corporate.my.com/LuCRE/LuCRE.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_iLuCRE"
contract="LuCRE.iLuCRE" name="BasicHttpBinding_iLuCRE" />
<endpoint address="http://wsvc.corporate.my.com/International/DialingService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDialingService"
contract="DialingService.IDialingService" name="WSHttpBinding_IDialingService" />
</client>
</system.serviceModel>
I used WCFTestClient to test it, however the service does work. I added the service reference to my project and I don't know the code details.
Updated:
If I used the code
DialingServiceClient client = new DialingServiceClient();
Then call the method through client, then everything is fine. Why?
Your binding element security is None. You need to also mention it when defining programmatically.
WSHttpBinding bindingDialingType = new WSHttpBinding
{ Security = new WSHttpSecurity { Mode = SecurityMode.None } };

How do I configure the buffer size and max message size in the ASP.NET Web API

We used to have these properties in the WCF Web API configuration.
MaxBufferSize = int.MaxValue,
MaxReceivedMessageSize = int.MaxValue,
If you're self-hosting, it's part of the HttpSelfHostConfiguration class:
MSDN Documentation of the HttpSelfHostConfiguration class
It would be used like this:
var config = new HttpSelfHostConfiguration(baseAddress);
config.MaxReceivedMessageSize = int.MaxValue;
config.MaxBufferSize = int.MaxValue;
You may want to look at httpRuntime section in web.config of your ASP.NET application. They are not named exactly the same, but there may be an analog for what you're trying to do. For instance:
<configuration>
<system.web>
<httpRuntime maxRequestLength="16384" requestLengthDiskThreshold="16384"/>
</system.web>
</configuration>
Note: Int32.MaxValue is 2,147,483,647
first i would have done this configuration in the WCF App.config
<endpoint address ="" binding="basicHttpBinding" bindingConfiguration="basicHttp" contract="AddSubService.IService1">
<!--
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>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
</binding>
</basicHttpBinding>
</bindings>
Then try updaeting the reference in the ASP.NET side which is calling the WCF in the web.config check that the endpoint has changed to the same.
I solve this problem making a dynamic binding before like this
BasicHttpBinding bind = new BasicHttpBinding();
bind.OpenTimeout = bind.CloseTimeout = bind.SendTimeout = bind.ReceiveTimeout = new TimeSpan(0, 30, 0);
bind.MaxBufferSize = int.MaxValue;
bind.MaxReceivedMessageSize = int.MaxValue;

Setting WCF Endpoint address at runtime?

If I have the following:
WSHttpBinding binding = new WSHttpBinding();
EndpointAddress endpoint = new EndpointAddress(new Uri("http://xxx:pppp/MyService"));
MyServiceClient client = new MyServiceClient(binding, endpoint);
How can I set the endpoint bindingConfiguration? If it helps my app.config is set to:
<endpoint address="http://xxx:pppp/Design_Time_Addresses/WcfServiceLibrary/ManagementService/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IManagementService"
contract="ServiceReference.IManagementService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
However I'm looking to let the user configure this before running the client.
Thanks
Very simple fix!! Sorry to ask a silly question!
binding = new WSHttpBinding("WSHttpBinding_IManagementService");
To set your binding administratively you need to add a binding section to your app.config file:
<system.serviceModel>
{...}
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IManagementService" {other parameters ...} />
</wsHttpBinding>
</bindings>
{...}
</system.serviceModel>
And if you do not feel confortable with the manual editing, you can use the WCF Service Configuration Editor which you can find in the Visual Studio menu Tools>WCF Service Configuration Editor.

Categories

Resources