In this post I’ll discuss the problems and solutions regarding an assembly or web site containing a web reference (using a web service) to a web service that had its schema modified and updating web reference is needed.
You have an assembly or web site containing a Web Reference and the web service schema is modified. The possible modification result will be:
- Runtime error – calling to a web method that it’s prototype changed or the web method has been removed.
- No Error just empty result – one of the parameter names is modified (even only upper to lower case change) the deserialize of the soap request just is not recognize so the parameter is deserialized into null (see note).
- Missing info – for example add values to Enum is not updated.
Note: the framework deserialization of XML throws an exception only in case of a mismatch of types in the inner XML. In case of a changed or missing property or member name the mismatch name will be set to its default value – so if no exception was thrown it doesn’t mean that the deserialized process succeeded.
The trivial solution is to right click in VS on the web reference and just press update web reference in order to update the web service proxy. Then rebuild the assembly or web site containing the web reference. The problems raised are:
- The web service modification requires an action (update web reference) and is not automatic.
- The need for rebuilding after updating web reference – sometimes the whole web site.
The problem arose in my work many times because we have a lot of web services that several web sites use. Sometimes a small modification in a web service requires updating a web reference and then rebuilding of many web sites (just for adding new Enum value for example).Often, we don’t get a compilation error due to a changed web method prototype, because we forgot to update the web reference and we crash at runtime. I hope the motivation is clear, let’s move to the solution.
There are 2 ways to solve this problem:
- Runtime proxy solution.
- Build process solution.
1. Runtime proxy solution
This solution is suitable for external web services that are not maintained by you.
You can generate the web service proxy at runtime. Read the following link about Web Reference Class . I won’t go into detail about this solution I’ll just mention some of its disadvantages:
- This method is not strong type so we will crash in runtime only if the web method prototype was change, and the code is less legible in that case.
- Performance: do not generate to proxy more then once because this action has an high cost (you could use a static object or single tone design pattern to counter this problem).
2. Build process solution
This solution is suitable for in house web services part of the same product.
This solution is a way to update the web reference automatically during the build process. The client that uses the web service doesn’t add a web reference, instead simply add a regular reference (DLL file) which contains the proxy.
In order to create this proxy DLL follow these steps:
- Create a new class Library project.
- Add to the project two classes: QueryHandler.cs and SDQueryHandelr.cs
QueryHandler.cs is empty, it will be generated automatically during the build process (pre-build event).
SDQueryHandelr.cs contains the constructor of the proxy: we can set the web service URL, time out and more…
public partial class QueryHandler :
WebServiceProxyConfigSection confSec = ConfigMgr.
if (confSec == null)
throw new Exception(“Problem in reading admin WS proxy config file”);
Url = confSec.URL;
Timeout = confSec.TimeOut;
PreAuthenticate = true;
Credentials = System.Net.CredentialCache.DefaultCredentials;
- Go to Project properties and in the build events set the pre-build event command line:
The Pre-build Content (this is the main idea):
- WebServiceReflector.exe X:\Binaries\Debug\Facade.QueryDispatcher.ServiceImplementation.dll $(ProjectDir)\..\AdminHost\Service.asmx – This Runs an application that generates a WSDL file without a need of a web host. We are using the in house application WebServiceReflector (written by Ami Yolovich) which generates a WSDL file by the web service .asmx file and the service implementation DLL. Here is another application that generates a WSDL file without web hosting of web service.
- “C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\”wsdl.exe /out:$(ProjectDir)\QueryHandler.cs $(ProjectDir)\..\AdminHost\Service.wsdl – Generating the code inside the file QueryHandler.cs using the SDK application WSDL.exe.
- cscript replace.vbs “$(ProjectDir)\QueryHandler.cs” “public QueryHandler()” “private void DummyCtor()” – Replacing the constructor generated in the previous line to a private method called DummyCtor: this allow us to implement the constructor in the SDQueryHandler.cs file, using vbs script for replacing string inside a file.
If you aren’t building the web service you can remove stage 1 and just use the existing WSDL by adding to your web service URL the suffix: ?wsdl (e.g. http://localhost/mywebservice.asmx?wsdl) if the web service is online.
- build the project and the proxy is updated automatically.
- now we can add this class library to each client that wishes to use this web service:
QueryHandler queryHandler = new QueryHandler();
Response res = queryHandler.InvokeMethod(request);
Note: building the proxies must be post building of the web service.
Note: we are building the clients (the web service consumers) after building the proxy project –> now if one of the web service methods was modified and the client uses this web method we’ll get compilation error.
Choose your suitable solution by your the web services characteristics and your product demands.
So that’s all for now d-: