Setting WCF Endpoint address at runtime? - c#

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.

Related

Programmatically define the Endpoint and Binding

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.

WCF client in a universal app

Is it possible to call a WCF service from a universal application?
I added a service reference and the proxy was generated just fine.
But when creating a NetTcpBinding programmatically and passing that to the proxy's constructor the service model throws the exception PlatformNotSupported.
Both running the app in the simulator and on the local machine generates the same exception.
An exception of type 'System.PlatformNotSupportedException' occurred
in System.Private.ServiceModel.dll but was not handled in user code
"this operation is not supported"
EndpointAddress address = new EndpointAddress("net.tcp://test:9000/ServicesHost/PublishService");
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
PublishingService.PublishClient proxy = new PublishingService.PublishClient(binding, address);
Does anybody have an example of a working WCF client in a UAP?
EDIT
It has something to do with the service being a duplex service!
The original contract:
[ServiceContract(CallbackContract = typeof(IPublishCallback))]
public interface IPublish { }
After removing the CallbackContract attribute the UAP client can create a connection, so basic WCF works.
So I guess it's better to rephrase the question.
Is it possible to create a duplex WCF client in a universal application?
edit servicemodel for the host
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpPublishService" openTimeout="00:00:10" receiveTimeout="infinite">
<reliableSession inactivityTimeout="24.20:31:23.6470000" enabled="true" />
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehaviour" name="PublishService.Publish">
<endpoint binding="mexHttpBinding" name="mexPublishService"
contract="IMetadataExchange" />
<endpoint address="PublishService" binding="netTcpBinding" bindingConfiguration="netTcpPublishService"
name="netTcpPublishService" contract="PublishService.IPublish" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8004/ServicesHost/PublishService" />
<add baseAddress="net.tcp://localhost:9004/ServicesHost/PublishService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Yes, it is possible. This is how i connect in a sample app i did a while ago:
using Tradeng.Srvc.Client.WinAppSimple.SrvcRefTradeng;
private InstanceContext instanceContext;
private TradengSrvcClientBase serviceProxy;
instanceContext = new InstanceContext(this);
serviceProxy = new TradengSrvcClientBase(instanceContext);
bool result = await serviceProxy.ConnectAsync();
if (result)
{
// connected...
}
I used the binding from the config file that is generated when you add a reference to your service.
This is what the app looks like. Cutting edge stuff.... :O)
https://www.youtube.com/watch?v=YSg6hZn1DpE
The service itself is running as a WebRole on Azure, by the way.

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;

how to get this config value from app.config?

My friend has the following app.config. He wants to get the value of address. how to do it?
<configuration>
<system.serviceModel>
...
<client>
<endpoint address="http://ldo:8080/LLService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ILLService" contract="LLServiceReference.ILLService"
name="WSHttpBinding_ILLService">
<identity>
<userPrincipalName value="ggldoe#mail.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
...
</configuration>
try this to Get first endpoint
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
ServiceModelSectionGroup serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup(configuration);
ClientSection clientSection = serviceModelSectionGroup.Client;
var el = clientSection.Endpoints[0];
return el.Address.ToString();
Take a look at the <system.serviceModel> documentation in MSDN.
You should:
Call the ServiceModelSectionGroup.GetSectionGroup method
Choose an endpoint from the serviceModelSectionGroup.Client.Endpoints collection. Presumably you want to look at a specific contract.
Look at that endpoint's Address property

Categories

Resources