Reading endpoint from config file in workflow service - c#

I know how can I read information from the config file in the activities by using C#
var servicesSection = (ClientSection)WebConfigurationManager.GetSection("system.serviceModel/client");
ChannelEndpointElement endpoint = servicesSection.Endpoints[0];
But when I try to read this information in the if statement of the workflow service, it doesn't work.
I tried the following code to read the endpoint information from the web.config file.
((ClientSection)WebConfigurationManager.GetSection("system.serviceModel/client")).Endpoints[0].toString().Equals("");
but it doesn't work.
some how, it doesn't understand the type casting and I can't convert the GetSection output to a clientSection object. do you know how can I do that in the if statement of the workflow service?( check something from the config file before calling some other activities)

I had similar requirement, after some prototyping, I managed following way. Hope this will help you and others.
/* Using in System.ServiceModel.dll */
using System.ServiceModel.Configuration;
using System.Web.Configuration;
/* Inside any method */
var clientSection = ((ClientSection)(WebConfigurationManager.GetSection("system.serviceModel/client")));
if (clientSection != null)
{
foreach (ChannelEndpointElement endPoint in clientSection.Endpoints)
{
..... endPoint.Name / endPoint.Address etc.
}
}
You can read any element from configuration and cast it to appropriate element type.

To read endpoint, binding and other sections from app.config, there are defined set of Section classes that help us read settings.
For example, to read list of bindings, we could simply use,
private void GetNetTcpBindingName()
{
Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ServiceModelSectionGroup serviceModel = ServiceModelSectionGroup.GetSectionGroup(appConfig);
BindingsSection oBinding = serviceModel.Bindings;
List<BindingCollectionElement> bindingCollection = oBinding.BindingCollections;
NetTcpBindingCollectionElement netTCPBindingCollectionElement = (NetTcpBindingCollectionElement)bindingCollection.Where(obj => obj.BindingName.Equals("netTcpBinding")).SingleOrDefault();
if (netTCPBindingCollectionElement != null)
{
Console.WriteLine(netTCPBindingCollectionElement.ConfiguredBindings.ElementAt(0).Name);
}
}
Given the following app.config XML (section of interest in bold),
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITrainerManagement" />
</basicHttpBinding>
**<netTcpBinding>
<binding name="NetTcpBinding_ILiveStream">
<security mode="None" />
</binding>
</netTcpBinding>**
</bindings>
<client>
<endpoint address="net.tcp://sever-pc/PST.TS.LiveStream/LiveStream.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ILiveStream"
contract="LiveStreamServiceReference.ILiveStream" name="NetTcpBinding_ILiveStream" />
<endpoint address="http://10.5.50.115/PST.TS.TrainerService/TrainerManagement.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITrainerManagement"
contract="TrainerManagementServiceReference.ITrainerManagement"
name="BasicHttpBinding_ITrainerManagement" />
</client>
</system.serviceModel>
Hope this helps. This can be used to read any standard settings.

Related

ASP.NET MVC : could not find endpoint element with name contract

I had created an MVC application that had no authentication so I was advised to create a mvc project that has the 'Individual User Accounts' option selected which brings with it some controllers, models and views.
What I had done to keep my old class library data was rename the current class library as Projectold in my file explorer and created a new class library in Visual Studio with the same name(Project) then imported all the controllers, views, config files that I had from my previous library and included them in the new class library.
I have a proxy to 2 web services that exposes data for me to use. Because I only needed a new class library, I had the existing <system.serviceModel> tag already there in the existing service folder so I just copied and pasted it within the new web.config file in the new class library.
What has happened is that now I cannot access the web service to access the data. I am thrown the error:
System.InvalidOperationException
HResult=0x80131509
Message=Could not find endpoint element with name 'WebServiceSoap' and contract
'ProxyToWebService.WebServiceSoap' in the ServiceModel client configuration
section. This might be because no configuration file was found for your application, or because no
endpoint element matching this name could be found in the client element.
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
My web.config file is (The proxy URL's have been anonymised):
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="WebServiceSoap"/>
<binding name="SWebServiceSoap"/>
</basicHttpBinding>
<customBinding>
<binding name="WebServiceSoap12">
<textMessageEncoding messageVersion="Soap12"/>
<httpTransport/>
</binding>
<binding name="SWebServiceSoap12">
<textMessageEncoding messageVersion="Soap12"/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://URL/URL/URL.asmx" binding="basicHttpBinding" bindingConfiguration="WebServiceSoap" contract="ProxyToWebService.WebServiceSoap" name="WebServiceSoap" />
<endpoint address="http://URL/URL/URL.asmx" binding="customBinding" bindingConfiguration="WebServiceSoap12" contract="ProxyToWebService.WebServiceSoap" name="WebServiceSoap12" />
<endpoint address="http://URL/URL/URL.asmx" binding="basicHttpBinding" bindingConfiguration="SWebServiceSoap" contract="ProxyToSWebService.SWebServiceSoap" name="SWebServiceSoap" />
<endpoint address="http://URL/URL/URL.asmx" binding="customBinding" bindingConfiguration="SWebServiceSoap12" contract="ProxyToSWebService.SWebServiceSoap" name="SWebServiceSoap12" />
</client>
</system.serviceModel>
I have returned to a back up copy and it works before I replace my old new class library with my new class library so the endpoint connections should be okay. Just when they are used in the new class library is where it breaks.
I cannot just copy the old web.config file either as because the Individual User Accounts option is selected, it has modified the web.config file.
My code for the proxy connection:
public InboundService()
{
proxy = new WebServiceSoapClient("WebServiceSoap", "http://URL/URL/URL.asmx");
Sproxy = new SWebServiceSoapClient("SWebServiceSoap", "http://URL/URL/URL.asmx");
}

Script component with WCF Invalid contract attribute in app.config

I'm trying to configure a script component with a service reference to my WSDL file inside this boiler plate method.
public override void CreateNewOutputRows()
{
//create instance of service client
}
However I'm running into problems with the configuration file app.config which is complaining about an invalid contract attribute contract="ServiceReference1.IClientService1
All attempts to change this manually have failed. Similar posts suggest using a fully qualified name Service.MyService but I'm not having any success so far. Is there a way to specify the binding programmatically?
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IClientService1">
<security mode="Transport" />
</binding>
<binding name="BasicHttpBinding_IClientService11" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://server/services/ClientService1.svc/soap"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IClientService1"
contract="ServiceReference1.IClientService1" name="BasicHttpBinding_IClientService1" />
</client>
</system.serviceModel>
</configuration>
Stub code looks like following
public override void CreateNewOutputRows()
{
string endpoint = "https://server/services/ClientService1.svc";
ClientService1Client client = new ClientService1Client(endpoint);
client.ClientCredentials.UserName.UserName = "";
client.ClientCredentials.UserName.Password = "";
Output0Buffer.name = client.GetActiveClients()[1].name.ToString();
}
I believe your issue may be due to having /soap in your endpoint address
<endpoint address="https://server/services/ClientService1.svc/soap"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IClientService1"
contract="ServiceReference1.IClientService1" name="BasicHttpBinding_IClientService1" />
I think it should just be:
address="https://server/services/ClientService1.svc"
As for creating the binding programmatically this should work or get you started:
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
EndpointAddress address = new EndpointAddress("https://server/services/ClientService1.svc");
ClientService1Client client = new ClientService1Client(binding, address);

WCF channelfactory with settings from the config file?

I have a server&client solution that are using WCF. The client will ask a service about the URL to an active server at runtime and to be able to set this I use ChannelFactory. I however still needs to use all other WCF settings from the config file. This is how I do it :
var clientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
var address = string.Empty;
for(int i = 0; i < clientSection.Endpoints.Count; i++)
{
if(clientSection.Endpoints[i].Name == endpointConfigurationName)
{
var endpointAddress = new EndpointAddress(clientSection.Endpoints[i].Address.ToString());
var netHttpBinding = new NetHttpBinding(clientSection.Endpoints[i].BindingConfiguration);
var serviceEndpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(T)), netHttpBinding, endpointAddress);
var channelFactory = new ChannelFactory<T>(serviceEndpoint);
break;
}
}
The problem is that I got 2 BehaviorExtensions that are used by some of the endpoints like this.
<services>
<endpoint binding="netHttpBinding" behaviorConfiguration="protoEndpointBehavior" address="BinaryHttpProto" bindingNamespace="http://MyApp.ServiceContracts/2007/11" contract="MyApp.ServiceContracts.IMyAppClientService" />
</services>
<behaviors>
<endpointBehaviors>
<behavior name="protoEndpointBehavior">
<protobuf />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67" />
</behaviorExtensions>
</extensions>
The question is how I read this from the clientSection.Endpoints? and sets it on the channelFactory? I know that I could create then manually like this :
serviceEndpoint.EndpointBehaviors.Add(new ProtoEndpointBehavior());
serviceEndpoint.EndpointBehaviors.Add(new CustomMessageInspectorBehavior());
But then this will be a hard coded static and it will apply to all endpoints, I need to be able to change it from the config.
You don't need to create the ChannelFactory by yourself. Just create a ClientService class that inherits from ClientBase<T>. The constructor of the ClientBase<T> accepts a EndpointName and adds automatically the behavior that is associated with this Endpoint. The ClientBase<T> also give you the possibility to access the ChannelFactory<T> and you can open as much channel as you want. the only thing that you need further to do, is to add a name for each EndPoint in the config that you want to use.
<endpoint binding="..." name="MyEndPoint" ... />
I hade to create everything in code, a mixed solution was no good, not in my case where I use alot of custom stuff.

how to read endpoint address value from app.config [duplicate]

This question already has answers here:
Read WCF service endpoint address by name from web.config
(3 answers)
Closed 1 year ago.
I have asp.net web application and have the following in my app.config file.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Test" />
<binding name="Test1">
<security mode="Test" />
</binding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://test:90001"
binding="basicHttpBinding" bindingConfiguration="Test"
contract="Test" name="HTTP_Port" />
</client>
</system.serviceModel>
How i can get/read endpoint address value?
I have come accross the this solution but it is not working for me asking for exe file path. Not sure which exe path file?
var serviceModel = ServiceModelSectionGroup.GetSectionGroup(ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None));
var endpoints = serviceModel.Client.Endpoints;
foreach (ChannelEndpointElement e in endpoints)
{
if (e.Name == "HTTP_Port")
Console.WriteLine(e.Address);
}
Console.ReadLine();
To read endpoints from appconfig you need to add reference of System.ServiceModel.Configuration and use GetSectionGroup method which return the serviceModel group and you can access all the endpoints in that section,if you just need the one you can access specific with the endpoint name.
Also in the appconfig you provided the port is invalid, I got and error while reading the url with that port I assume you just added that as an example.

BasicHttpBinding from app.config inaccessible in code

I have several web services that I am connecting to from a Visual Studio C# project using service references. Two of the service references were created and work without a problem, and one of them took quite a lot of effort to get imported, and now seems to not be working.
I believe the problem lies in the app.config file since it is getting a "Could not find endpoint element" error when I try to create the client.
Here is the app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="RateQuoteSoap">
<security mode="Transport" />
</binding>
<binding name="RateQuoteSoap1" />
<binding name="QuoteSoap" />
<binding name="WebservicePrimusSoapBinding" />
</basicHttpBinding>
<customBinding>
<binding name="QuoteSoap12">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint
address="https://webservices.rrts.com/rating/ratequote.asmx"
binding="basicHttpBinding"
bindingConfiguration="RateQuoteSoap"
contract="RoadRunnerService.RateQuoteSoap"
name="RateQuoteSoap" />
<endpoint
address="http://services.echo.com/Quote.asmx"
binding="basicHttpBinding"
bindingConfiguration="QuoteSoap"
contract="EchoService.QuoteSoap"
name="QuoteSoap" />
<endpoint
address="http://services.echo.com/Quote.asmx"
binding="customBinding"
bindingConfiguration="QuoteSoap12"
contract="EchoService.QuoteSoap"
name="QuoteSoap12" />
<endpoint
address="http://api.shipprimus.com/"
binding="basicHttpBinding"
bindingConfiguration="WebservicePrimusSoapBinding"
contract="PrimusService.WebservicePrimusServicePort"
name="WebservicePrimusServicePort" />
</client>
</system.serviceModel>
</configuration>
The PrimusService is the one that is not working correctly, and the full error when I try to initialize the client like WebservicePrimusServicePortClient serviceClient = new WebservicePrimusServicePortClient("WebservicePrimusServicePort"); is
System.InvalidOperationException: Could not find endpoint element with name 'WebservicePrimusServicePort' and contract 'PrimusService.WebservicePrimusServicePort'in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.
I have also tried to simply initialize a BasicHttpBinding object using the binding name and the endpoint name with no luck (short variable names for readability)
BasicHttpBinding a = new BasicHttpBinding("QuoteSoap"); // Works fine
BasicHttpBinding b = new BasicHttpBinding("WebservicePrimusSoapBinding"); // Fails
BasicHttpBinding c = new BasicHttpBinding("WebservicePrimusServicePort"); // Fails
It throws no error for binding a, but binding b and c fail with the error:
System.Collections.Generic.KeyNotFoundException: No elements matching the key 'WebservicePrimusSoapBinding' were found in the configuration element collection.
While not a direct solution, I ended up just taking the information from the app.config and creating my own BasicHttpBinding and EndpointAddress objects in code. This is more of a workaround than a fix for the problem, and I still don't know why I couldn't access the information in the app.config directly.
I followed the solution in this answer about how to consume a service without using the app.config file.
I created my BasicHttpBinding like
BasicHttpBinding binding = new BasicHttpBinding();
binding.Name = "PrimusServiceBinding"; // Completely Unnecessary
and my endpoint like
EndpointAddress endpoint = new EndpointAddress("http://api.shipprimus.com/");
and could connect to the service and retrieve information without a problem, even providing as little information as I did (basically just the address).

Categories

Resources