I have added reference to a WCF service that has two end points. On adding the service the following get added to the Config file:
<client>
<endpoint name="ABCServiceV1" address="http://staging.ABCwebservices.com/ABC/Service.svc"
binding="basicHttpBinding" bindingConfiguration="ABCServiceV1"
contract="ABCService.IService" />
<endpoint name="ABCServiceV2" address="http://staging.ABCwebservices.com/ABC/Service.svc/20"
binding="basicHttpBinding" bindingConfiguration="ABCServiceV2"
contract="ABCService.IService1" />
</client>
The code to create the client is as as below:
ABCService.ServiceClient ABCClient = new ServiceClient("ABCServiceV2");
However, I am getting an runtime error - "Could not find endpoint element with name 'ABCServiceV2' and contract 'ABCService.IService' 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."
if i used ABCService.ServiceClient ABCClient = new ServiceClient("ABCServiceV1"); then everything works fine. But when using ABCServiceV2 it is trying to look for Contract - ABCService.IService - when it should be looking for - ABCService.IService1.
How do i make it look for the correct contract?
If you added a second reference to a different service (ABCServiceV2) then I believe this will have generated a second service class for ABCServiceV2. The two classes will implement separate contracts (ABCService.IService and ABCService.IService1) so you won't be able to interchange the endpoints.
I believe you should be able to initialise your two service endpoints like so:
ABCService.ServiceClient ABCClient = new ServiceClient("ABCServiceV1");
ABCService.Service1Client ABCClient1 = new Service1Client("ABCServiceV2");
Even though this post is old and answered, the answer didn't help in my case.
My problem was I generated the service client with the svcutil.exe tool, but didn't specify any namespace at all; and so the contract namespace name was generated as the target namespace of the schema document by default, yes total mess.
On the other hand I was trying to use the config file generated when a service reference is added to the project. The contract namespace in this file is ServiceReference1 (by default) or any other name you want, perfect storm! But all I had to do was to remove the namespace part from the FQN from the <endpoint>'s contract attribute, and the contract became visible to the CLR.
Hope this help others
Related
I try to use web service for weather
http://www.webservicex.com/globalweather.asmx?WSDL
I make console application and try to use this service. First of all I add reference and name the reference WeatherService and write below code
Console.WriteLine("Now we get weather, please wait .......");
WeatherService.GlobalWeatherSoapClient w = new WeatherService.GlobalWeatherSoapClient();
Console.WriteLine(w.GetWeather("Lahore","Pakistan"));
But it gives me a exception
Additional information: An endpoint configuration section for contract 'WeatherService.GlobalWeatherSoap' could not be loaded because more than one endpoint configuration for that contract was found. Please indicate the preferred endpoint configuration section by name.
I am learning web services and don't know why this happens. Any one help me on this is great favor. Advance thanks.
Open your app.config, find needed then pass it's name to GlobalWeatherSoapClient(here):
in your app.config should be setting like this:
<endpoint address="http://www.webservicex.com/globalweather.asmx"
binding="basicHttpBinding" bindingConfiguration="GlobalWeatherSoap"
contract="WeatherService.GlobalWeatherSoap" name="GlobalWeatherSoap" />
get name and pass it to client:
WeatherService.GlobalWeatherSoapClient w = new WeatherService.GlobalWeatherSoapClient("GlobalWeatherSoap");
I would like to use structuremap to inject a wcf client but I also would like that this client reads the endpoint and binding configurations from the config.
I tried the following:
For<IServiceClient>().LifecycleIs(new UniquePerRequestLifecycle()).Use<ServiceClient>().
Ctor<string>("endpointConfigurationName").Is("WsHttpBinding_IService");
But this will result in the error:
StructureMap Exception Code: 205\nMissing requested Instance property \"remoteAddress\" for InstanceKey \"e50e036b-9d71-47de-8ac2-d53a641e9be8\"
When I pass the remoteAddress it work's like expected:
For<IServiceClient>().LifecycleIs(new UniquePerRequestLifecycle()).Use<ServiceClient>()
.Ctor<string>("endpointConfigurationName").Is("WsHttpBinding_IService")
.Ctor<string>("remoteAddress").Is("https://myurl/Service.svc");
I don't understand why the first constructor overload does not read the endpoint address from the config?
The config looks like this:
>
<client>
<endpoint address="https://myurl/Service.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService" contract="IService" name="WsHttpBinding_IService" />
</client>
The first overload does probably read the endpoint address, but StructureMap never calls this first overload, but always calls the most greedy constructor. Prefer using the Use method and supply a factory delegate:
For<IService>()
.LifecycleIs(new UniquePerRequestLifecycle())
.Use(() => new ServiceClient("WsHttpBinding_IService"))
This forces the use of the right constructor for this generated class. Perhaps it's even better to hide that class behind a proxy. This way to can hide the annoying quirks of WCF from your application. And for types that you create yourself, prevent having multiple constructors.
I have a small WCF Client which I'm trying to configure for service discovery via the application configuration file - however whenever I do this:
// Create a new DiscoveryClient instance from the 'DiscoveryEndpoint'
// configuration in App.config
DiscoveryClient discoveryClient = new DiscoveryClient("DiscoveryEndpoint");
I get an ArgumentNullException, Value cannot be null. Parameter name: contract. There is no contract parameter for this overload of the DiscoveryClient constructor, and the contract is correctly specified in the App.config (see below).
Here are the relevant sections of the App.config:
<system.serviceModel>
<client>
<endpoint name="DiscoveryEndpoint"
contract="IExampleContract"
kind="dynamicEndpoint"
endpointConfiguration="DynamicEndpointConfiguration"/>
</client>
<standardEndpoints>
<dynamicEndpoint>
<standardEndpoint name="DynamicEndpointConfiguration">
<discoveryClientSettings>
<endpoint kind="udpDiscoveryEndpoint"/>
<findCriteria duration="00:00:02">
<types>
<add name="IExampleContract"/>
</types>
<scopes>
<add scope="urn://wcf.test.com/examples/exampleContract/development"/>
</scopes>
</findCriteria>
</discoveryClientSettings>
</standardEndpoint>
</dynamicEndpoint>
</standardEndpoints>
</system.serviceModel>
This is targetted at .NET Framework 4.0, using Visual Studio 2010 SP1.
The documentation for this overload of the DiscoveryClient(string) constructor indicates that this should create a new DiscoveryClient instance with the configuration identified in App.config.
Has anyone else encountered this behaviour, and if so how did you resolve it?
The "DiscoveryEndpoint" that you defined in the config file is actually a service client end point, not the DiscoveryClient end point.
The following should work:
var exampleContractChannelFactory = new ChannelFactory<IExampleContract>("DiscoveryEndpoint");
var exampleContractClient = exampleContractChannelFactory.CreateChannel();
// You can now invoke methods on the exampleContractClient
// The actual service endpoint used by the client will be looked up dynamically
// by the proxy using the DiscoveryClient class internally.
OK, I've spent a lot of time in the debugger with the Enable .NET Framework source stepping option enabled, and I've found that the cause of this exception being thrown is (probably) a bug in the implementation of the way that the DiscoveryClient is instantiated from the configuration file - there is a call way down the call stack which passes a hard-coded value of null into a contract parameter, which is where the originating exception is thrown.
So, after much head-scratching, and lots of searching, I've come up with the following workaround (well, more like a total HACK:!) - which I'm posting here to help out anyone else who might encounter the same issue.
// HACK: The following is a workaround for a bug in .NET Framework 4.0
// Discovery should be possible when setup from the App.config with the
// following three lines of code:
//
// discoveryClient = new DiscoveryClient("DiscoveryEndpoint");
// Collection<EndpointDiscoveryMetadata> serviceCollection = discoveryClient.Find(new FindCriteria(typeof(IExampleContract))).Endpoints;
// discoveryClient.Close();
//
// However, a bug in the Discovery Client implementation results in an
// ArgumentNullException when running discovery in this way.
//
// The following code overcomes this limitation by manually parsing the
// standard WCF configuration sections of App.config, and then configuring
// the appropriate FindCriteria for a programmatically configured discovery
// cycle. This code can be replaced by the above three lines when either
// 1. The bug in .NET Framework 4.0 is resolved (unlikely), or
// 2. The application is retargeted to .NET Framework 4.5 / 4.5.1
//
// To aid future developers, this HACK will be extensively documented
// Load the App.config file into a ConfigurationManager instance and load the configuration
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Get the ServiceModel configuration group
ServiceModelSectionGroup serviceModelGroup = ServiceModelSectionGroup.GetSectionGroup(configuration);
// Get the StandardEndpoints configuration node
StandardEndpointsSection section = serviceModelGroup.StandardEndpoints;
// Get the DynamicEndpoint configuration node
Configuration dynamicEndpointConfiguration = section["dynamicEndpoint"].CurrentConfiguration;
// Get the first DynamicEndpoint configuration
// HACK: This assumes only one DynamicEndpoint configuration exists
// No additional configurations will be interpreted. This should
// not pose a problem as typically a client will only access a
// single service instance. This can be extended if necessary
// at a later time.
DynamicEndpointElement element = ((DynamicEndpointElement)serviceModelGroup.StandardEndpoints["dynamicEndpoint"].ConfiguredEndpoints[0]);
// Set the required Contract Type
// HACK: This is currently hard-coded to prevent the need to specify
// an AssemblyQualifiedName in the App.config file. This will
// not typically pose a problem as each client will typically
// only open a single service exposing a single, well-known,
// Contract Type
FindCriteria criteria = new FindCriteria(typeof(IExampleContract));
// Add all required Scopes to the FindCriteria instance
foreach (ScopeElement scopeElement in element.DiscoveryClientSettings.FindCriteria.Scopes)
{
criteria.Scopes.Add(scopeElement.Scope);
}
// Get the Discovery Duration
criteria.Duration = element.DiscoveryClientSettings.FindCriteria.Duration;
// Create a new Discovery Client instance
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
// Retrieve the matching Service Endpoints via Dynamic Search
Collection<EndpointDiscoveryMetadata> serviceCollection = discoveryClient.Find(criteria).Endpoints;
// Close the Discovery Client
discoveryClient.Close();
// HACK: END -- Process the results of Discovery
Note that I'm assuming that this issue is resolved in .NET Framework 4.5 / 4.5.1 - it may not be, but I cannot test that at the moment.
If anyone else has an alternative solution, more elegant or efficient than this, please post it to help others.
I generated a proxy via this command -
svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config https://service100.emedny.org:9047/MHService?wsdl
and then copied the elements from the resulting app.config into the app.config file of an existing project.
When I try to access the client in that config file via-
MHSClient serviceProxy = new MHSClient("MHSPort");
it should reference the second client below:
<client>
<endpoint address="https://webservices.hmsa.com/EDI27X/cstc/Hipaa27XService.svc"
binding="customBinding"
bindingConfiguration="wsHttpEndpoint"
contract="HIPAA27XServiceContract"
name="wsHttpEndpoint" />
<endpoint address="https://12.23.28.113:9047/MHService"
binding="customBinding"
bindingConfiguration="MHService_MHSPort"
contract="MHS"
name="MHSPort" />
</client>
but instead I get the error;
Could not find endpoint element with name 'MHSPort' and contract 'MHS' 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.'
If I go to definition of MHSClient, it takes me to the proxy.cs file and this line;
public partial class MHSClient : System.ServiceModel.ClientBase, MHS
solved with the following-
endptAddress = new EndpointAddress(new Uri("uri"/xxxx"), EndpointIdentity.CreateDnsIdentity("xxxxxx"), addressHeaders);
MHSClient serviceProxy = new MHSClient(b, endptAddress);
solved with the following-
endptAddress = new EndpointAddress(new Uri("uri"/xxxx"), EndpointIdentity.CreateDnsIdentity("xxxxxx"), addressHeaders);
MHSClient serviceProxy = new MHSClient(b, endptAddress);
#Guanxi gave me the clue when asking about endpoint address from the config file. Once I created the endpoint address then I could instantiate/create the service using the correct overload;
var b = new CustomBinding() as the first argument and for the second argument,
the correct endpoint address.
complicated - WS-Security - IBM Websphere server interop <-> wcf client within the context of various .NET and Visual Studio implementations of web services... oh my
You probably need to set the ConfigurationName property of the ServiceContractAttribute above the service contract interface, ConfigurationName should match your contract name.
'VB.NET:
Imports System.ServiceModel
<ServiceContract([Namespace]:="http://yournamespace", ConfigurationName:="MHS")> _
Public Interface MHS
//C#:
using System.ServiceModel;
[ServiceContract(Namespace="http://yournamespace", ConfigurationName="MHS")]
public interface MHS
Look at the auto generated code here:
MSDN: How to: Create a Windows Communication Foundation Client
Also worth looking at:
MSDN: ServiceContractAttribute Class
I have a web reference to web-service:
using (var client = new GetTemplateParamSoapClient("GetTemplateParamSoap"))
{
TemplateParamsKeyValue[] responsArray = client.GetTemplatesParamsPerId(
CtId, tempalteIds.ToArray());
foreach (var pair in responsArray)
{
string value = FetchTemplateValue(pair.Key, pair.Value);
TemplateComponentsData.Add(pair.Key, value);
}
}
Tried to change a web-reference url from c# code: as advice here:
1) http://www.codeproject.com/KB/XML/wsdldynamicurl.aspx
2) How to call a web service with a configurable URL
3) http://aspalliance.com/283_Setting_Web_Service_References_Dynamically
But I get symbol is missing when trying to do:
client.Url
In addition I couldn't find a property of "Url_behavior"
It sounds like you've already added the service reference, but here's a walkthrough on adding, updating and removing service references.
Once you've got one of those in your project, you can alter the endpoint URI with one of the constructor overloads, as John Saunders said above. To do this, you'll need to know the name of the endpoint in your config file. For instance, after you add your service you might have elements like this in your config file:
<endpoint address="http://bleh.com/services/servicename.asmx"
binding="basicHttpBinding" bindingConfiguration="ServiceNameSoap"
contract="ServiceReference1.ServiceNameSoap" name="ServiceNameSoap" />
Given that endpoint, you can change the address at runtime by using the following overload:
var proxy = new ServiceReference1.ServiceNameSoapClient("ServiceNameSoap",
"http://new-address.com/services/servicename.asmx");
You can also do it after construction, but that becomes a little bit harder. If you need to do so, see the documentation on the Endpoint property and the associated type ServiceEndpoint.