Be Careful When Using Enums in Web Services

We know that when enumeration type is used in web services, the string name of the enumeration value is used but not the underlying integer. Even if you remember this rule by heart, sometimes it is still to make mistakes, especially during the development phase when developers tend to include the web service with the project he develops rather than to deploy the service and then access it from the project via web references.

To illustrate the potential danger of enum type not used correctly in a web service, I created a trivial web service as below:

public enum TestEnum

{

Item1 = 10,

Item2 = 20

}

[WebService(Namespace = “http://tempuri.org/”)]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class TestWebService : System.Web.Services.WebService {

public TestWebService()

{

}

[WebMethod]

public int Test1(TestEnum e)

{

return Convert.ToInt32(e);

}

[WebMethod]

public TestEnum Test2(TestEnum e)

{

return e;

}

}

Basically, Test1 method returns the underlying integer value of the enum parameter passed in and Test2 simply returns what’s being fed back to the caller.

As a test, let’s first call the service within the same project (no web references). The code I use to test is:

protected void Page_Load(object sender, EventArgs e)

{

TestWebService ws = new TestWebService();

int i = ws.Test1(TestEnum.Item2);

int j = (int) ws.Test2(TestEnum.Item2);

}

And as we expected, both i and j are 20 at the end of the call. This is intuitive enough. The behavior of the web service call changes however, when the web service is deployed. To illustrate, let see what would happen when the service is accessed from a web reference.

protected void Page_Load(object sender, EventArgs e)

{

localhost.TestWebService ws = new localhost.TestWebService();

int i = ws.Test1(localhost.TestEnum.Item2);

int j = (int) ws.Test2(localhost.TestEnum.Item2);

}

The code here is almost identical to that I used previously, except this time the web service is referenced. And when you run this code, you will see that i is 20 and j is 1 not 20.

How could this be? Well, remember that when enumeration type is used in web services, the string name of the enumeration value is used but not the underlying integer. In the first example when the web service is called directly from within a project, the actual class reference is used even though the methods are decorated as webmethods. But in the second example, the web service call is made through the proxy class and when accessing TestEnum from the webservice, the items would be assumed to be 0 based independent of how you set them in the webservice code. So naturally, when we convert it to integer, j becomes 1 (because it is the second enum item). But Test1 converts the enum value to integer on the web service side so i remains 20.

To avoid this problem, we should always use the enum itself as parameters and results when calling web services, because the underlying integer value are interpreted differently depending on where the interpretation is made (webservice side or client code side).

Be Sociable, Share!

Leave a Reply