I want to invoke a web service in my C# client application.
I want to be able to bind to this web service dynamically.
I am using the following code for dynamically calling a web service:
class Program
{
interface IInterface
static void Main(string[] args)
{
BasicHttpBinding bin = new BasicHttpBinding();
EndpointAddress endPoint = new EndpointAddress("http://api.wxbug.net/webservice-v1.asmx");
IInterface myInterface = ChannelFactory<IInterface>.CreateChannel(bin,endPoint);
}
}
My question is, how to I generate a ServiceContract Interface for my web service? Is there any tool to autogenerate this? This is because my target web service is quite complex with lots of exposed methods, and I dont want to write the Service Contract Interfaces all my hand.
The svcutil tool is what you use for this. This is also what gets run behind the scenes when you select "Add Service Reference" in Visual Studio.
If you are working in Visual Studio, then "Add Service Reference" will probably be easiest, as it should automatically start up your service in order to get the metadata.
If you can't or don't want to use Visual Studio, you'll need to make sure your service is up and running, and then use svcutil.exe (if you open a .Net Command Prompt it will be in the path variable). Using svcutil is sometimes necessary if you don't want to generate/overwrite the client configuration, or if you want to specify a specific class for the proxy to go in. There's also a handy switch in svcutil which will generate generic collections in the proxy, rather than defaulting to arrays.
You can to right click your project and to select Add Service Reference; it'll grab your web service WSDL and to create your proxy classes.
Related
This seems very trivial, but it is not working for me at all. I am attempting to call a soap web service from within my c# console application. The app is built for .net 4.5. Here's what I did:
Added the service reference to the project in visual studio 2013 by pointing it to the wsdl. It finds the Service and it's operations fine.
Attempt to create an instance of that service by doing the following:
ServiceReference1 s = new ServiceReference1();
I get the following error code:
Project1.ServiceReference1 is a 'namespace' but is used like a 'type'
Any ideas? I've searched for this for a while and can't come across someone having the same problem with a real solution. I will provide any more info needed.
If you already added the service reference to the project you see the reference. In this case you left a default name 'ServiceReference1'.
Now you want to call the web service's methods, for this you have to instantiate a SOAPClient.
ServiceReference1.YourWebserviceNameSoapClient client = new ServiceReference1.YourWebserviceNameSoapClient();
client.HelloWorld(); // call of webmethod
now you access the webmethods under the 'client' object.
When you create a service reference, Visual Studio 2013 will generate a proxy class you can use to transparently call into the service. The default proxy namespace is your_project_name.ServiceReference1. The type is the name of your service.
For an example service http://localhost/YourService.svc.
You generate the Service Reference ServiceReference1 from your console project ConsoleApp. The generated files have the namespace ConsoleApp.ServiceReference1. The type is YourService.
var service = new ServiceReference1.YourService();
will return an instance of the proxy generated by Visual Studio. Then you will be able to call any of the service methods.
I created a WCF ServiceContract with a few methods but when I add the reference to the client none of them show up. The WCF Test Client loads correctly and all the methods show up there. They also show up in the 'Add Service Reference' window when I try to add the service reference and click 'Go' ('Discover' does not bring anything up). What may be keeping the Interface on the client side empty?
Here is the code for the service with one method:
namespace WS
{
[ServiceContract]
public interface Itest
{
[OperationContract] method_name(int num);
}
}
The client app recognizes the namespace but does not find any methods in it.
Thanks!
Try following things.
Make sure your service is working using test client in visual studio.
Update your service reference by right clicking on it.
Or delete it and add new service reference again.
Can you try using svcutil.exe and see if you are able to create a proxy file. If you are then you can try referencing that in you client project.
something like:
svcutil.exe <<url where service is deployed>> /o:ClientProxy.cs
I've been experimenting with moving a web service from the old fashioned asmx technology to the newer WCF, and I think I'm missing something fairly basic about how to reference it.
When I choose, "Add Web Reference" and point to the WSDL I get all of the relevant classes from the wsdl defined, plus a class with static methods to call them, such as this:
TrackService service = new TrackService() { Url = "https://gateway.fedex.com:443/web-services" };
When I choose "Add Service Reference" I get almost all of the same classes generated, such as TrackRequest, TrackReply and so on, but no TrackService class. So I can build up the request object, but don't know how to invoke the service. I tried searching through the generated classes for "service" or "client" but can't find anything.
It was there, but strangely named as FedexTrackService.TrackPortTypeClient
The ONLY argument I can see for SOAP WCF over REST (json) wcf is the fact that once my service is created I can add a a reference in visual studio and I get a load of strongly typed classes ready for me and a client class that I can call all my webmethod through. It even sets up the web.config as far as I remember.
However when I expose a REST (json) service I still get a WSDL. So Im wondering is there still a way to build my references automatically?
Not using WCF tools. Unlike with SOAP (which has an established protocol for describing services - WSDL), REST doesn't. WADL is one such protocol, but it isn't too widespread and WCF does not support it. You still get a WSDL, because WCF will describe everything it can from the service. However, the WSDL won't have a <wsdl:port> element, which would describe the REST endpoint, which is why you get the WSDL, but cannot generate a reference to it.
The post at http://blogs.msdn.com/b/carlosfigueira/archive/2012/03/26/mixing-add-service-reference-and-wcf-web-http-a-k-a-rest-endpoint-does-not-work.aspx has a lot more info on this issue.
Very old question, newer answer.
today using openapi (swagger) I can achieve this by using swagger inspector doing samples i can document my rest services as well as create a spec yml/json file allowing for validations and acceptance criteria as well as automated clients for java,python,c#,ruby,javascript and others I'm sure
I would like top elaborate:
Although it is true you cannot get a WSDL add service reference with a JSON REST WCF service, what I do is create two met data hooks:
is the operations returning JSON
is a single XML op returning a class wrapper which includes all the service classes I allow, I call it Discover:
i.e.
public class Discover
{
public Manager Manager {get;}
public Employee Emp {get;}
....
}
[OperationContract]
public Discover DiscoverDTOs()
You can, indirectly. While the client generated by Visual Studio won't work, that client implements an interface, also generated, that you can use like this:
WebChannelFactory<IService> factory = new WebChannelFactory<IService>(new Uri(endpointAddress));
IService proxy = factory.CreateChannel();
int result = proxy.Operation(1, 2, 3);
WebChannelFactory has another overload which accepts a WebHttpBinding, you can configure based on the service configuration, or you can make this configuration manually in your app.config file.
Which one of this two ways of using wcf service is better? why?
Generating proxy from Service Reference
using ChannelFactory
ex.
ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>();
IMyContract proxy1 = factory.CreateChannel();
proxy1.MyMethod();
It is a bit boring to call wcf service like so
IMyContract proxy1 = null;
try
{
proxy1 = factory.CreateChannel();
proxy1.MyMethod();
((ICommunicationObject)proxy1).Close();
}
catch
{
((ICommunicationObject)proxy1).Abort();
}
Should we repeat this snippet for every proxy call? Or Is there generic way to create a wrapper class for closing and aborting proxies?
Is writing class like this ServiceExecution.Execute(proxy=>proxy.MyMethod()); which creates proxy, and closes or aborts it good way to do that?
Here is an MSDN post, that recomends not to use generated proxies in .Net 3 because it creates ChanelFactory each time, .Net 3.5 ChanelFactory is cached.
But personally I prefer to use ChanelFactory myself, generated code is always a pain even after partials come out
In first case when you use VS to add Service Reference it generates all the code for you including ServiceContrcats and DataContracts.
But when you use ChannelFactory you must have service contracts and etc on client side already.
I suggest using approach 1.
I've found this blog with an example including source code that also explains how to properly handle the connection (closing, aborting, etc.). The blog also contains links for more details at MSDN.
Manually creating the service proxies from a running service might be a good alternative. The tool svcutil is what Visual Studio uses under the hood when adding a service reference. Using this, you can generate the proxy class in a common location, and then link to it in each project you require, and also gain better control over your proxy classes.
For example, to generate a proxy for a service called TestService running locally on port 8000, you would run the following in the Visual Studio command prompt, generating a proxy class TestServiceProxy.cs in the proxies directory.
cd "C:\src\proxies"
svcutil /noLogo /out:TestServiceProxy http://localhost:8000/TestService
There are some other useful parameters for the tool, for example:
Add /n:*,WcfServices.TestService will specify a namespace for the proxy class.
Add /config:TestServiceProxy.config and svcutil will generate a sample configuration file for using TestService including endpoints, bindings etc.
Add /r:"Common.dll" and the proxy class emitted by svcutil will not have definitions for types used by the service, but defined in the assembly Common.dll.
Use svcutil /? for more information.