difference between adding service reference and proxy class in WCF - c#

I am new to WCF and wondering if there any difference between Proxy class and adding a service reference in client application?
Thanks

Adding service reference or generating proxy classes through svcutil.exe are basically the same. The first one actually calls svcutil like API to generated proxy classes in the References folder.
Using svcutil.exe you will get more fine grained control, which is good for big projects and long term maintenance, because command line options give you more flexibility than GUI of adding service reference.
And if you want to automate the generation of proxy classes and you develop both service and client, you may refer to this link at
is there a way to automatically update proxy object when updating service on WCF?

is not any difference in the level of use, they are two proxies.
Service reference: the advantage that gives you is, when you want to upgrade the service you can do directly from VS ("Update Service Reference), otherwise you'll have to do it manually.
you can find all infos in http://msdn.microsoft.com/en-us/library/bb628652.aspx

Related

What does "Add Service Reference" really do?

Forgive me if the question is incoherent.
I find WCF really complicated. Moreover, different ways to do the same thing make a beginner even more befuddled, like hard-code a host vs config file, or hard-code a client vs add service reference. (Am I feeling right?)
I think it would be helpful to try to go through the process with code in a primitive way. No service reference, no config file.
Maybe I can put it this way: If the service is running on another machine (or my machine pretending another machine), what are the minimum things it has to provide beside an address for some one to consume it?
And how can I consume it with code?
Add Service Reference parses the WSDL of the service to import the service contract, and potentially any referenced domain types, into the client's representation (in this case, C#). It generates a proxy which exposes a C# interface that represents the service contract. The proxy is a namespace and set of classes with methods to call each service method for the particular endpoint.
In short it takes service contract metadata and reifies it to C#.
You can also manually generate the proxy with 'svcutil.exe'
svcutil http://server.com/FooService/FooService.svc /out:FooProxy.cs
Or to include generation of the app.config as well
svcutil http://server.com/FooService /out:FooProxy.cs /config:App.config
Visual Studio "Add Service Reference" does that for you, plus adds the new files to your project.

WCF Client generation possible based on ServiceContract alone?

I have a Visual Studio Solution in which a WCF server is contained; the service is defined as an interface using the ServiceContract attribute. The service is finally hostes via an instance of ServiceHost using HttpBinding, which is the intended behaviour.
In the same solution, there is a client; currently the hosted service is consumed by starting the server manually and generating a proxy class using "Add Service Reference", which can be updated as soon as the server is running.
While this works in the sense that the outcome is as desired, I wonder if it is possible to remove the manual start of the server to update the service reference in the client. Is it possible to build the client by just sharing the DataContract attributed interface between server and client without actually running the server and importing the service definition manually in the client? If yes, how can it be done?
Another way is to use svcutil to generate proxy, but even that require WSDL metadata to generate proxy and that is usually available by starting service, you can save it once from the running server and you can use that to generate proxy without starting server later on.
see different options http://www.codeproject.com/Articles/33297/WCF-Proxy-Generation-Options
I personally like hand crafted client as I have better control on code/error handling and I can use shared DTOs from common dll.
Yes, you can use a common data contract, shared between the client(s) and host, to maintain the interface between both sides. That's what I do with this big data sync WS built on BasicHttpBinding.
In a nutshell, I have a host project, with a service contract and the functioning/processing code, referencing a very small project (and DLL) containing only the data contract class definition; just class, constructor, variables and in/out parameters.
That same small project containing the data contract is also referenced by a client-side project that handles all of the interaction between our client programs and the Sync WS. We actually have every web service call (from the simplest Ping() function to the most complicated RetryFileUpload() function) running through that data contract. All the string-based parameters and binary data is passed through the data contract class, then seriailized or deserialized on the receiving end.
Having said that, this approach only works when you have .NET code on both the client and host. We also have Android and iOS clients that are forced to emulate this behavior ... which isn't a big deal, obviously. But this is the approach we took.

Consuming the same WCF service from different addresses

I have a single WCF service but, until runtime, I don't know the correct address of the service. It may be :
http://example1.com/MyService.svc
// or
http://example2.com/MyService.svc
The service is used by a class library (DAL). I have two options:
Add a service reference to the
service (Visula Studio 2010) and
change the address at run-time. This
way VS-2010 will create WSDL and
other stuff for me (I'm not sure if this is even possible).
Create the proxy on the fly and set
the base service address. This needs
more work and if I make any change
to service, I need to generate WSDL
myself. Maintenance of this code is
not as easy as option one.
Which option to use? Also if option two is recommended by you, then should I my client wrapper class be singleton or I can create all the connection stuff on each call?
you can point to localhost or any other address in development then in production if the url changes you simply modify the web.config or the app.config where you have configured the WCF end point.
Option 1 - you get all the advantages and none of the pain. Just use something factory-oriented (i.e. Don't do new MyProxy(), but instead stick that code somewhere central like a static CreateMyProxy() method, or consider an IoC/DI container).
How to consume WCF web service through URL at run time?

Creating web service and client with shared types

I have created two wsdl files with shared types imported from xsd schema file.
After that I have created web services using interface generated by wsdl.exe tool with parameter /serverInterface.
Frist web service, have web method “RegisterData” with put into queue some complex object to be processed, by system “A”. As result of this method is returned Boolean (with tell us that object was registered successful).
Second web service, have web method “UpdateData” to update some data in system “B” based on this same object , with was changed in process on system “A”.
So in system “A” I have to create client for second web service, where I will call method “UpdateData” with this modified complex object us argument.
But when I’m creating this client in Visual Studio (by add web reference or add service reference) I have to create some namespace for client. And then when I’m trying to call “UpdateData” agument have different namespace for this same object received from first web service “RegisterData” method.
I would like to create first web service and second web service client , where I can use this same type object between them.
Thank you very much for help.
I don't believe this is possible with ASMX web services.
WCF does support this, however.
WCF Links:
WCF Developer Center
Beginner's Guide to Windows Communication Foundation
How to: Configure a Service to Reuse Existing Types
Actually, I think I may have misread your question. I though you were trying to share the same types between the client and the server. ASMX cannot do that. However, it appears you are trying to share the same types between two client proxies. You can do that easily using the WSDL.EXE tool.
Consider a schema, DataTypes.xsd, and two WSDL files that import it, ServiceA.wsdl and ServiceB.wsdl. To create the server interfaces, use:
wsdl /serverInterface /n:SharedTypes.Servers /out:Services.cs ServiceA.wsdl ServiceB.wsdl DataTypes.xsd
This will create interfaces which you can implement in order to create your services. These interfaces will both use one set of classes created from DataTypes.xsd. To create the proxy classes, simply use:
wsdl /n:SharedTypes.Proxies /out:Proxies.cs ServiceA.wsdl ServiceB.wsdl DataTypes.xsd
Notice that you do not need the /sharedTypes switch. That has a different purpose. It is for combining types of external services when you need to download the WSDL and any XSD from the service.
I have tried this using an example like yours, ServiceA posting a message into a queue, and a client picking up that message and sending it to ServiceB. It works quite well.
I agree that it is not possible to do this via the VS Web Reference functionality. To meet your requirements you can use the wsdl.exe utility with the /sharetypes switch.
For more information see Web Services Description Language Tool (Wsdl.exe)

wsdl.exe/svcutil.exe - is there a way not to generate the classes for types in the xsds during a Web service or client generation

We have a centrally managed object model for types in the schema in C#.
We want every one across the enterprise use that object model instead of using the one generated each time from wsdl/svcutil during a webservice client or service implementation.
is there a parameter(any other way) to wsdl/svcutil not to generate classes for the schema types during theie execution?
I believe what you are looking for is: svcutil.exe /r your-dtos.dll
/reference: -
Reference types in the specified
assembly. When generating clients, use
this option to specify assemblies that
might contain types representing the
metadata being imported. (Short:
/r)
In my opinion the tight coupling of the WCF proxy, endpoint channel, service operations and dto payloads into the same generated client proxy is a major design flaw.
This is what spurred me to solve in my open web services framework where I decouple the end point and payload which allows:
The same web service client (i.e. Soap11, Soap12, XML, JSON) to be able to call any web service.
It lets me also use the same DataContract dto instance in any of the web service clients
This has many benefits including being able to expose the same web service on a number of different end points without any extra configuration. Thus providing optimized web service endpoints for each consumer of my service. E.g.
XML for interoperability and strongly-type clients,
JSON for Ajax clients,
WSDL's for environments that prefer generated code (i.e. Flex Builder, VS.NET 'Add Service Reference' etc)
At my company we have developed hundreds of web services called by a number of different clients i.e. Ajax, Flash/ActionScript, C++, Silverlight, ASP.NET and being able to call the same web service through different endpoints has saved us countless hours.
I don't know of any specific setting or command line switch to enforce this - what you can do, but that's mostly a matter of training and enforcing by checking, is to share the class library (the assembly, in a DLL) with the developers, and make sure that everyone references that common class library and leaves the default settings in the "Add Service Reference" dialog (on the "Advanced" page) alone:
Here, you define that WCF will reuse any types it can find in any of the referenced assemblies - so if your developers add a regular reference to the common data contracts library, then WCF will use those types instead of re-creating them over and over again.
But again - that's only a "management by example and checking" kind of approach - I don't know of any technical way to enforce this.
If you remove the mex endpoint from the service config file, the client app will not be able to discover and generate the proxy objects.
A way to handle this situation if I understand your question correctly is to do the following:
Create a common set of DLLs that has the service, and datacontracts / shared object model.
Create a service using the contracts in the common dll instead of the contracts visual studio creates when you create a new service.
Remove the MEX endpoint from the server config file (this will essentially break proxy generation).
Have your client use the the common dll and manually create the channels on the client side (via channel factory etc...).
In this approach you do not use wsdl.exe/svcutil.exe at all since you are essentially bypassing the wsdl. You do not add service references either since you are manually managing the connections.
EDIT: Following this approach, the client can still try to generate proxy objects via wsdl.exe/svcutil.exe, but they won't get the correct information from the wsdl. They'll essentially generate a non-functioning / incomplete proxy.

Categories