I have a solution that contains two projects (web services and client application).
When i built solution, i always need to update Web References manually (web service's proxies).
Is there any way to do it automatically with MSBuild?
You should be able to use svcutil.exe to create the proxy for you. You just have to get all the parameters right.
You could share contracts via a Contracts DLL if that makes sense for you from a design perspective (you'll be breaking loose coupling) and you have the tooling (the WCF wizards make it easier to do)
Related
This might get a little convoluted so please let me know if you need clarification.
I have a solution which contains the following projects
Project A - WPF application
Project B - ASP.NET application (with exposed webservices)
Project C - Class Library
Both project A and project B reference types that are located in project C, but more importantly project A makes webservice calls to project B using types located in project C.
The problem I am running into is it appears that when making webservice calls I have no way of referencing the types located in project C directly but rather need to use the types as exposed by the webservice.
Now the basic idea of why this is done I understand (obviously typically the consumer of your webservice would only have the WSDL to go from) however in my case this is an internal application (which is part of a single solution) so this is not a concern.
The biggest problem I see with continuing this approach is that any updates to the types in project C will need to be reflected in project B and then "refreshed" in project A. This seems pretty nasty to me. Surely there is a smoother path?
Am I wrong? What is a typical approach to this issue?
You may be a little confused here.
The types in Project C and the types you see when you add a reference to your web service are different.
When you added the Web Service reference. Visual Studio used svcutil.exe, read metadata from your web service (I'm assuming .asmx?) and then created proxy classes for you.
Check the types for the Web Service (they will obviously have the same names). Put your cursor on them and pres F12. It'll take you to some designer generated code.
So there is no real workaround as such. When you update your types in Project C and then Update your web services in Project B . You will have to Update Service Reference from Project A Which again uses svcutil.exe and regenerates all your proxies.
Also, this is the same way WCF Services work too.
#giddy is correct - the types exposed by the web service are different to the types contained in Project C - even though their definition may be identical. The web service exposes type information via a wsdl, which Visual Studio uses to generate proxy types.
There is a way around this - you can create an interface which declares all the methods in the web service class, and include it in your shared library. You can then skip the "Add service reference" process, and create the web service proxy with code (you will not need the proxy classes, as you use the classes in the shared library).
Either way, if you make a change to your data transfer objects or the web service class, you will need to update the client by either by requerying the wsdl using "refresh service reference", or by copying the shared library over.
I have a wpf application with multiple projects. I'm wondering if it's best to have one project that handles all the web services and have each project reference this one project. Is this even possible, or does each project need to handle its own web services?
This is possible and would be a great way to seperate your web services to be used by other parts of your system.
If you create one project that has WCF, ASMX or any other type of service you can add a web service reference to your other projects or hook it all up manually! The individual projects can pass in configuration properties (URLs, or any other pieces of data) or defaults could be set in the web service project itself!
You can absolutely do that! In fact, I'd say it's preferred - that way your single web service project can be re-used by different clients, whether it be WPF, Silverlight, or ASP.NET MVC (using AJAX). For example:
WebServiceProject
WpfProject
SilverlightProject
Projects 2 and 3 would have a Service Reference back to project 1, thus eliminating the need to possibly duplicate data access code.
Here is the MSDN reference page for adding Web References in Visual Studio.
Hope this helps!
I'm going to create a new PayPal project. Should I just create a regular Class Library project then add the reference to the WSDL? We are not using WCF. I just want to know what the best project type / template I should use if I'm going to share this project with lets say another WAP web project. I simply want to create wrappers for some of the WSDL that we'll be using in part of the PayPal API.
Yes a class library project seems the right thing to use if you're wrapping the code that consumes a web service.
Unless it's going to be tiny (say, just one class) in which case you might want to include it in an existing common project that is already used by both of your consuming projects, just to keep everything a little simpler.
We have lots of WCF services that are only used by our own code; the code that uses them is mostly in the same solutions files that contains the services.
However they do not use a shared assembly for the contracts, so each time a data contract is change the reference to the service has to be updated by hand in all projects that use the service. (Then the code needs to be fixed up by hand)
So how do I do a simple refactoring like renamed a data item in a data contract?
Is there a way to update all references to services in a single solution with one command, rather then having to click on each reference in each project?
You may have already answered you own question here.
Move your data contracts to a shared "Contracts" project, which will allow you to use the built in Refactor -> Rename option in Visual Studio to change the name, with the change being reflected in all of the projects in the solution.
Update
To clarify, the Contracts project is an internal "organisation" of your contracts. It allows many of your projects to reference one set of contracts. For example...
WCF service exposes "List GetCustomerById(int id)".
WCF service may call down to a processing layer, which might need to calculate something using another project etc. All of thes projects can use the single "Customer" definition from your Contracts project.
Any consumer of the WCF service would get the definition of the Customer via the service reference. You wouldn't share your Contracts project or send the dll for their use.
With your current settings you can't do it because you are regenerating the proxy each time. This is good from SOA perspective as data contract should not change very often. But if you are controlling both client and service and it is all .Net you can do as Shonee suggested. Use the /r option in svcutil to generate the proxy from the common assembly. Then you can refactor easily.
Do you use auto-generated WCF service references in line of business applications? Or do you roll your own? And why?
EDIT
For anyone looking to roll their own, I found this article which may prove useful: Understanding WCF Services in Silverlight 2. There's another article on the site for Silverlight 3 which may be a useful addition: Understanding WCF Faults in Silverlight 3.
I typically roll my own, or tweak the ones generated by the auto-generated wizard.
I have two scenarios, most of the time:
I control both ends of the wire - in that case, I share the assembly with the service and data contracts between the service and client, and in that case, I write my own clients from scratch, as ClientBase<T> descendants or using a ChannelFactory<T>. Unfortunately, this is not an option with a Silverlight client, as far as I know :-(
I get WSDL+XSD from a third party - in that case, I typically use svcutil.exe to generate a first version of the client proxy, and then I tweak that to suit my needs (especially the configs generated by svcutil or VS "Add Service Reference" are horrendously bad.....)
I just like to have that extra control of doing it myself and totally knowing what's going on.
I haven't had to use Silverlight to access a service I didn't control, but in accessing a WCF service that I do control, yeah, I use the standard auto-generated WCF references. Rolling my own would just be too painful when the service is changing regularly.
If you control both ends of the service, you should also strongly investigate RIA Services, which implements a much more elegant way of keeping your Siverlight client in sync with your WCF service than having to manually regenerating your service references each time the interface changes.