How to create a client proxy in WCF with the right command? - c#

Different from the last command in doc https://learn.microsoft.com/en-us/dotnet/framework/wcf/how-to-create-a-wcf-client, the program hints me to use 'svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config http://localhost:8000/ServiceModelSamples/service?wsdl' to generate client proxy code and the config file when I follow the tutorial exactly.
So I have two questions.
Does base address must start with 'http://'? Just like what is shown in https://learn.microsoft.com/en-us/dotnet/framework/wcf/how-to-host-and-run-a-basic-wcf-service. Can I use some other kind of base address if I don't use http binding?
If the answer to #1 is yes, what will the command be? It's better if you can give me an example.

Yes the base address must start with http or https because it needs to be hosted on a web server (like IIS). If you have done that you need to create a service reference to your project via: right click "Connected Services" --> add "Service reference" then type in your address choose your .svc file --> choose a name (e.g. ServiceRef) and click ok..
Then add your proxy to execute methods from the service like:
ServiceRef.ServiceRefClient proxy = new ServiceRef.ServiceRefClient();
bool testresult = proxy.TestConnection();

Related

Configure WCFservice client using web.config when added as connected service (sdk-project style)

We converted our projects to the 'new' SDk format csproj files. To add a new WCF webservice we right-click the project and choose: Add => Connected Service. Then we choose 'Microsoft WCF Web Service Reference Provider'. That all works, but the generated code does not contain an option to pass an endpoint name to the service-client constructor (which was an option in the older csproj add service reference option) so it would do a lookup in the web.config-file to configure the service (endpoint and behaviours e.d).
It looks configuration is all hardcoded in the generated service code file (servicereference.cs). I know it's a partial class and could just add an extra constructor accepting an endpoint name as a string like ctor(string enpointname):base(endpointname){} but i'm lazy and believe it should be able to work out of the box.
I think the question (and comments) contains the answer already. The only way to use the Config-file is to add a constructor in partial class in a new file.

Supporting WCF in ASP.NET MVC

I'm trying to make the same project to work with WCF and MVC.
My problem is:
MVC is working perfectly, than I included the interface and the .svc that I had in WCF service.
When I try something like this:
http://localhost:2986/PAGENAME.svc
I get the following error:
The resource cannot be found.
NOTE: PAGENAME.svc is in root (and so as the interface).
Looking forward this problem, I included the ignore methods in RegisterRoutes:
routes.IgnoreRoute("{resource}.svc/{*pathInfo}");
routes.IgnoreRoute("{resource}.svc");
But didn't work either =/
Does anyone know how to fix this?
Thank you!
You need to make sure that you have all the files required, which are referenced from the Service Host (.svc file), i.e.:
<#% ServiceHost Service="..."/>
Where Service specifies the service implementation.
The service contract (the interface that the service implementation implements) is usually configured in web.config.
You don't need to ignore the route if the service host file is at the root of your solution.
You need to reference System.ServiceModel.
If you want to test your service you can by opening visual studio command prompt and running wcftestclient, File -> Add service and add the url for your service, e.g.:
http://locahost:12423/MyService.svc
It's been a while since I've played with this, but I think when using MVC you need to register a service route... but I don't remember if that's what I had to do or if I just wanted to do that for cleaner routes.
To add a service using a service route, you would do something like the following
routes.Add("MyService", new ServiceRoute(
"some/path",
new ServiceHostFactory(),
typeof(MyService)
));

How to override target URI for a web service reference in VS 2008

This seems like it should be really simple, but I'm unable to figure this out.
I am adding a web service reference to my console application. The web service points against our production environment and I would like to test it against development. In VS2005 it was really easy to override the target URI of the service. Is it possible to do the same with VS2008? I would like to set the URI in code or via a config file.
I would really appreciate help with this. Thanks!
If you look in your .config, you should see <endpoint> elements that were added to the <client> section of <system.serviceModel>. Assuming you need to point at only one environment at a time you can simply edit the address attribute of those endpoints to point to whatever URL you want.
If you wanted to change this at runtime you need to use the constructor overload for the client proxy that was created. There should be several overloads that take a parameter called remoteAddress in many forms.
It seems that I was able to get around this issue by going to "Add Service Reference" -> "Advanced" -> "Add Web Reference". This gives me a reference in the form I am most familiar with. Now I was able to override the constructor with the URI parameter. Is that method frowned upon?

WCF and moving the proxy code to a DLL. Is it possible?

it looks like I am not able to succesfully move my WCF proxy code into a separate DLL (as opposed to an EXE as I can see in all the examples I have run into).
The reason I am trying to do this is that I would like my proxy code to be invoked by different clients (possibly unmanaged code), which might not know anything about WCF but just need to access to the services (through a Facade exposed by the proxy maybe?).
Whenever I move the following code that creates a new proxy to a different VS project within the same solution, I get the dreaded "Could not find default endpoint element that references contract 'localhost.IRemoteCommandService' in the ServiceModel client configuration section" exception.
localhost.RemoteCommandServiceClient proxy =
new localhost.RemoteCommandServiceClient();
The same code works smoothly whenever used within a Main method in the same project where the proxy code is (auto-generated from Visual Studio).
Any idea? I hope that the client code of my proxy does not need to have the service model XML configuration as the proxy, because that would defeat the purpose I am moving the WCF proxy code into a DLL in the first place.
Thanks,
Stefano
The endpoints are indeed normally specified in the configuration file. You must look at the serviceModel data in the config file, and copy it into your calling app.config - or you need to use the more verbose way of creating the proxies in your code (i.e. specifying the address, binding, configuration etc through code to the constructors).
If you don't want to have to endpoint configuration on the client, you'll have to embed it into your proxy dll by specifying everything in code.
Another option would be to use a dynamic proxy, like this one, which would allow you to not have the serviceModel in your client apps.

SOAP web service: many servers, one interface

I have a scenario in which I'm going to need an arbitrary number of servers to provide the same SOAP web service. I would like to generate one set of proxy classes and be able to supply them with a location to point them at the different servers at runtime. Unfortunately, it looks as though the wsdl:port node (child of wsdl:service) requires the address of a specific server to be hardcoded. It appears that due to this the URL will be baked into my proxy classes. I know that I could potentially modify this by hand-editing the generated proxy classes, or modifying the code generation, but I'd really prefer not to resort to that. I feel like there's got to be a better way to solve this problem. I just want to decouple the interface definition from the location that the service will be residing at. I'm using VS2008 and C#.NET if that's of any help though best would be a language-agnostic (SOAP or WSDL specific) general solution to this problem.
Why don't you load balance the web servers and then create a DNS entry for the load balanced IP address....essentially creating a web farm. This will allow you to reference the hostname rather than the static IP addresses and if you ever need to change the IP address of the load balancer or the web servers it is a one time change. Plus you then have redundancy and performance control.
If you're using a WebReference (pre-WCF) to get to the web service, you can simply set the Url property on the web service proxy class after you create it.
For WCF, you can provide a different endpoint address to the proxy class constructor, rather than using the default (among other possible solutions).
No, in .NET you can change the URL at runtime.
Service svc = new Service ();
svc.url = "Value read from config. file or some such"
output = svc.method (input);
When you add a web reference to your project, it places the address of the web service into the .config file of your application / web application. You can then simply change this setting in the config file to point to a different web service location, assuming of course that the services are identical.
The easiest solution would be to use a software load balancer such as HAProxy. At more cost, you could use a hardware solution such as Big-IP.
Here's a hint on how to decide the URL of WSDL. I´m just changing the port but it´s of course possible to make it more advanced.
public class PortChangeReflector : SoapExtensionReflector
{
public override void ReflectDescription()
{
ServiceDescription description = ReflectionContext.ServiceDescription;
foreach (Service service in description.Services)
{
foreach (Port port in service.Ports)
{
foreach (ServiceDescriptionFormatExtension extension in port.Extensions)
{
SoapAddressBinding binding = extension as SoapAddressBinding;
if (binding != null && !binding.Location.Contains("8092"))
{
binding.Location = binding.Location.Replace("92", "8092");
}
}
}
}
}
}
Put that in your Add_Code and add the following reference to your web.config.
<webServices>
<soapExtensionReflectorTypes>
<add type="Dev.PortChangeReflector,App_Code"/>
</soapExtensionReflectorTypes>
</webServices>
I hope you can get new ideas of this.
Client proxies have URL property you can set at runtime. To make it simpler, wsdl.exe utility has /appsettingurlkey key. When you generate a client proxy, it's constructor will check the key in appSettings and set the service URL accordingly. I believe WCF has this feature as well.
However, I would agree with #Matt and suggest you consider load balancing as the best solution in the long run.
Is this for scaling (each server provides the same data) or
for same API different data on each server?
For 2, then you can do as above, just change the service URL in code.
For 1, you could use round-robin DNS (e.g. you see multiple servers with at the command line type nslookup www.google.com).

Categories

Resources