Programmatically Changing the Default Collection for WCF Proxy Class - c#

I have an application where users will connect to one or more WCF services running on machines in their network. Because the address of these connections are not known at the time of installation, the application must programmatically connect to these services (i.e. I cannot use Add Service Reference). I have the connection working using the following code:
string url = "...the url...";
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress(url);
ILicenseService service = ChannelFactory<ILicenseService>.CreateChannel(binding, address);
However, some of the members of my service class return an ObservableCollection of elements. I know how to change the collection type in the Service Reference dialog box, using Advanced settings. However, I cannot figure out a way to set this value programatically so that my client knows to read the return type as an ObservableCollection instead of a List. Any clues?

It should deserialize to the type which is defined by the interface of the service class, or to the type of the property of the serialized object. Try just changing the collection type on the interface/class.
By the way, you stated that you cannot use Add service reference because the service endpoint address is not known at compile time, but that shouldn't stop you from using it. Obtain a copy of the WSDL and import it in Add service reference from local WSDL file, then when creating a service proxy specify the actual endpoint address as shown here.

Related

How to generate a WCF Client from the WSDL only for certain endpoints?

I have the WSDL of a large enterprise web service, which includes several endpoints, out of which I only intend to use one.
I tried generating the Service Client in Visual Studio by adding a Service Reference to the project. The issue is that due to the high number of endpoints available in the service, the generated client code in Reference.cs ended up having more than 1,400,000 lines, and Visual Studio seems to have a hard time handling it (IntelliSense often hangs, sometimes the whole VS crashes), and I imagine the build times will be longer too due to this.
And out of the hundreds of endpoints, I will only use one, and won't need the rest.
Is there a way to generate the Client code from the WSDL only for a certain endpoint, either with the Service Reference GUI of Visual Studio, or with svcutil? Or if not, is there some other straightforward way to do this?
I did not find any way to generate a client for a certain endpoint from the WSDL file. But you can call the service of an endpoint individually through the channel factory.Here is the demo:
EndpointAddress address = new EndpointAddress("http://localhost:8000/GettingStarted/CalculatorService1111");
BasicHttpBinding binding =new BasicHttpBinding();
ChannelFactory<ICalculator> factory = new
ChannelFactory<ICalculator>(binding, address);
ICalculator chanel = factory.CreateChannel();
You need to call that endpoint and pass in the address of that endpoint, define the corresponding binding, and then declare the channel factory. So you can call the method in the service. By using the channel factory you can call any endpoint of a service.

Having WCF service proxy configurable

I am writing a basic WPF GUI to connect to a WCF service and consume an interface. So far I have connected to the test system by creating a service reference, putting in the URI for the test service I want to consume, it finds the interface and creates the proxy via service reference for me.
What I want this to do when you run the GUI app is for the user to be able to pick an environment - development, test or production and for the GUI to then connect to the appropriate WCF service depending on the environment selected.
How can I do this?
You can overwrite the Endpoint like this:
client.Endpoint.Address = new EndpointAddress(GetAddressForCurrentMode())
The other way you could to it, is to write a method, maybe an extension method, that accepts the service contract and the implementation class. Further more it either accepts a configuration name, or an endpoint:
public static TClient GetServiceClient<TClient, TContract>(string endpoint)
where TClient : ClientBase<TContract>
{
// Construct client
}
To construct the client, use one of BaseClient<T> overloads (from MSDN).
To then consume the client, just use the method above as normal:
using(var client = ServiceInterop.
GetServiceClient<MyClient, IMyContract>("http://foo.bar"))
{
// Consume client
}

c#: How to consume webservice methods whose address is unknown at compile-time

I am consuming a webservice from a Java server. The webservice provides me with some methods that need. Up till now I have been using the method where I added the reference of the webservice in the project explorer, typed the address of the webservice and compiled it. But now I need it to pick up the address of the service at runtime from an xml file or something! is that possible?
There is Url property in generated proxy object that you can set at runtime. Covered in Creating the Web Service Proxy article on MSDN.
Sample from the article (shows how to also set credentials, you may also need to set Proxy):
var rs = new ReportExecutionService();
rs.Url = "http://<Server Name>/reportserver/reportexecution2005.asmx?wsdl";
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
Note that above answer is for case when you don't know exact Url of server till runtime, but you have WSDL/sample server available at design time and able to generate proxy via add web service in VS (or manually).
Alternatively you can call service via other classes implementing "HTTP GET" like HttpClient and configure anything you want, but will need to do your own parsing of results.

Wcf object types

Trying to send a complex type between two systems that have the same code base. They are both aware of the same object that is the data transport medium. However when I pass object on the consumer proxy it appears as an object in the web service namespace instead of the one in the application.
Is there anyway that I can define to use the internal object?
[WebMethod]
public void Run(TransportObject transport)
appears in my application under MyNamespace.Webservice.Transport instead of MyNamespace.Objects
As Henk says sharing of types in WCF is default behavior.
I will qualify that by expanding on it and demonstrating how to achieve it:
So rather than have visual studio generate a service reference for you, you can have WCF create the proxy when it executes by using ChannelFactory.
For example:
// Create service proxy on the fly
var factory = new ChannelFactory<IMyServiceContract>("NameOfMyClientEndpointInConfigFile");
var proxy = factory.CreateChannel();
// Create data contract
var requestDataContract = new MyRequestType();
// Call service operation.
MyResponseType responseDataContract = proxy.MyServiceOperation(requestDataContract);
In the above example, IMyServiceContract is your service contract, and MyRequestType and MyResponseType are your data contracts, which you can use by referencing the assembly which the service also references (which defines these types).
[WebMethod] implies it's an ASMX based service, not a WCF service...
Try again with an [OperationContract] in a [ServiceContract]
Sharing of Types in WCF is possible, I think it's even the default behaviour.

Call The Same WCF Service From Multiples Hosted Servers

I am a little consused with how to acomplish this task. The question is, How can I Call a WCF Services from Multiples Hosted Servers. The WCF is the same for all the Hosted Apps. Same Contract, Same Binding Type, Etc. I am trying to call it in this way because I will host the services in multiples Servers and I need the service to do the same in all of them. I have to call it from one client. VS 2010, .Net Framework 4.0., C#.
Thanks,
It depends how you plan to create service proxy in the client application. If you want to add service reference it is enough to add it from one server and then create separate endpoint configuration for other servers - all endpoints configurations will exactly same except the address (you can do the same in code). When you call services you will create proxy instance for each server and you will pass name of the endpoint (defined in configuration) for each server like:
foreach(var endpointName in myStoredEndpointNames)
{
var proxy = new MyServiceProxy(endpointName);
proxy.CallSomeOperation();
}
Another approach is not using add service reference. In such case you must share contracts between server and client application and you can use ChannelFactory. This class is factory for client proxies which are created by calling CreateChannel. You can pass endpoint configuration name, endpoint address or binding and endpoint address when calling this method.
I use a function like this:
public static MyWcfClientType GetWcFClient(string hostName)
{
MyWcfClientType client = new MyWcfClientType();
// Build a new URI object using the given hostname
UriBuilder uriBld = new UriBuilder(client.Endpoint.Address.Uri);
uriBld.Host = hostName;
// Set a new endpoint address into the client
client.Endpoint.Address = new EndpointAddress(uriBld.ToString());
return client;
}
Of course use your own type for the "MyWcfClientType"

Categories