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?
Related
I have a WCF Service (Service1) in localmachine and a Application consuming it.
There is a same WCF (Service2) in a another server(not local). Now if I want to delpoy my local application to server and some other person wants that application to consume service2 without any change in code. Is that possible?
Since my application only has Service1 reference.Is there any way to configure the service reference?
It shouldn't be an issue for a number of reasons:
The service names will probably be different meaning that it would be easy to point to the right service
It sounds like you have different applications on the same server (which is fine) which means that even if you had ServiceABC and ServiceABC the application names would be different meaning they could just point their application to App123.com/ServiceABC and you could point yours to App456.com/ServiceABC and there would be no issue
If I am understanding you correctly then there should be no reason to have to change any code that is currently pointing to the existing Service on the server
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.
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
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.
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.