I've been playing these last few days with ASP.NET WebServices [1], and, naturally, I've been running into a few snags. Yesterday I ran into what seems to be an inconsistency in the way XML serialization works where WebServices are invoked. Consider this simple ASMX file:
<%@ WebService Language="C#" class="WeirdBhv" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using System.Xml.Serialization;
[ XmlRoot(Namespace="/schemas/customer") ]
public class Customer
{
[ XmlElement("name") ]
public string Name;
[ XmlElement("phone") ]
public string Phone;
}
[ WebService(Namespace="/services/WeirdBhv") ]
public class WeirdBhv
{
[ WebMethod ]
public Customer GetCustomer()
{
Customer c = new Customer();
c.Name = "Tomas";
c.Phone = "12223222";
return c;
}
}
Now, here's the weirdness. If you invoked this webservice via the ASP.NET SOAP binding, the response would look something like this:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
string
string
Notice how the Customer instance is serialized on an element named GetCustomerResult. Now, if you were to invoke the service with the HTTP POST binding, you'd get this, instead:
string
string
Notice that this time the Customer instance is serialized with a Customer element name. My question is why this difference? I know that if I were to specify the element name in the XmlRoot attribute in the declaration of Customer, in both cases it would be serialized with that name. However, I find it very inconsistent that it doesn't use the same element name in both cases even if the XmlRoot didn't specify the element name to use.
[1] Yes, I've actually worked more with other toolkits, such as the SOAP Toolkit than with ASP.NET.... go figure.
2 Comments
archived from WordPress — closedWell, yes you can call it inconsistent - but I (and MS ;-) call it more like a convinient. As you are using a Document/literal ASMX based Web Service which aims at *messages* and not *RPCs* (you know this distinction and the ongoing discussions ...), the top element of the serialized instance is just a signal for what kind of message is sent back to the original caller ... nothing more. The inbound message is GetCustomer and the outbound is GetCustomerResult - you see: just XML block :-)
Just my 2 cents.
Cheers,
Christian
Ah, what I just wanted to add: the name of the element is defined in the Web Service's metadata (WSDL). You can control through an attribute how the whole thing should look like. E.g.
[SoapDocumentMethod(Action="http://www.contoso.com/Sample",
RequestNamespace="http://www.contoso.com/Request,
RequestElementName="GetUserNameRequest",
ResponseNamespace="http://www.contoso.com/Respone",
ResponseElementName="GetUserNameResponse")]
Cheers,
Christian