Tuesday, October 20, 2009

Weekly Source Code: Make Web Service Configurable

Sorry for the delay, been crazy at work.

In Visual Studio.Net you call web services like the old style ASP.Net web service (not new WCF) by adding a reference to the project using Add Web Reference option. In the pop up dialog you point it to the web service URL, Visual Studio.Net will then generate the required C#/VB.Net stub classes.

But its not to say that the web service will be at the same URL location expecially if you move between development - > QA -> production environments. How do you make the web service URL configurable?

The web service stub class Reference.cs (for C#) or Reference.vb (for VB.Net) has a URL property, you can always set this property in your code but its a nice way to rather do it when you call the constructor e.g.:

MyService service = new MyService(webserviceUrl);

You do this by adding the following constructor to the MyService class:

MyService(String theUrl)
{
Url = theUrl;
}

The downside (before Visual Studio.Net 2008) is that if you update the web reference (after adding an additional web method to the web service etc) the code get regenerated meaning your code will break and you will have to add the constructor again.

Fortunately Visual Studio.Net 2008 introduce partial classes which allow splitting definition of a class across multiple files.

The Reference.cs / Reference.vb class also is a partial class so you can add an additional partial class with the same name and same namespace:

public partial class MyService
{
MyService(String theUrl)
{
Url = theUrl;
}
}

Now you can update the web service reference without worrying about such problems.

So what is partial classes? Yes they allow you to split the definition of a class across multiple source files but why? In this sample it show that its for code generation mainly since you normally generate code then add your own additions (like a constructor in this case) but if you re-generate your custom code is lost. Partial classes (and later on I will introduce partial methods) resolve this problem. Why did MS add it? Look at LINQ to SQL which also generate code, now you can add custom logic like validation with partial methods without ever worrying that re-generation will break your logic.

2 comments:

Owe Jørgensen said...

Good article, Lennie!

Note that you don't have to do it that way -- you can also instanciate the webservice as usual and pass the Url value after instanciation.

string newUrl = "http://server/path/to.asmx";
MyService service = new MyService();
service.Url = newUrl;

This can also be achieved when working with C# revisions that support class initializers like this:

string newUrl = "http://server/path/to.asmx";
MyService service = new MyService {Url = newUrl};

PS: note that empty constructor calls can be omitted when using class initializers.

I'm not sure if this is possible in VB.net, but I suppose it should be.

Lennie De Villiers said...

Yes you can also set the Url property directly using the normal notation or object initializers. Regards Lennie