Some XmlSerializer Control in ASMX

A customer pinged me asking how to control various aspects of the XmlSerializer in ASMX. Here are a few of the ways that you can control the XmlSerializer and how it projects its contract through WSDL.

 

using System;

using System.Web.Services;

using System.Xml;

using System.Xml.Serialization;

 

 

[XmlType("CustomerType")]

public class Customer

{

private string _first;

private string _middle;

private string _last;

 

[XmlElement("MiddleName", Order = 2,IsNullable=true)]

public string Middle

{

get { return _middle; }

set { _middle = value; }

}

 

[XmlElement("LastName", Order = 3)]

public string Last

{

get { return _last; }

set { _last = value; }

}

 

[XmlElement("FirstName",Order=1)]

public string First

{

get { return _first; }

set { _first = value; }

}     

    

}

[WebService(Namespace = "https://www.fabrikam.com", Name="CustomerService")]

public class WebService : System.Web.Services.WebService

{

[WebMethod]

[return: XmlElement("PayingCustomer")]

public Customer FindCustomer(string id)

{

//TODO: Find a customer by ID

Customer c = new Customer();

c.First = "Kirk";

c.Last = "Evans";

return c;

}

}

 

In the wsdl:types section, you won't see "Customer"… you see a "CustomerType" defined. We control the complexType's name through the XmlType attribute, applied to our data transfer object.

The ordering of elements may be important to you. ASMX seems to order them alphabetically in WSDL. That is, the order in which they are serialized does not match how you lay them out in code. If this is important to you, then you control with the Order property of the XmlElement attribute on our data transfer object.

We control the shape of the response message in the wsdl:types section by defining the instance of our CustomerType as an element named "PayingCustomer". This is specified in the return attribute of the method marked with the WebMethod attribute.

You always want to provide your own namespace for your service. By specifying the namespace at the service level, the data transfer object is now part of that namespace as well. That is, the complexType "customerType" is bound to the namespace "https://www.fabrikam.com". You could control this in the data transfer object using the XmlType attribute or each individual XmlElement attribute to control the serialization.

Not a complete list, but handy to remember things like the return attribute.

And remember… this is still applicable in the WCF world as well. You can still use the XmlSerializer in WCF.