views:

2136

answers:

2

I have created a .NET web service that returns an object, say Class "getResponse".

The WS returns the following response ...

<getResponse xmlns="http://tempuri.org/getCustomer/wsdl/"&gt;
   <Result xmlns="http://tempuri.org/getCustomer/"&gt;
      <ResultCode>OK</ResultCode>
      <ErrorsList/>
   </Result>  
</getResponse>

while the client is actually waiting for the following... (note the "mes-root:" prefix)

<mes-root:getResponse xsi:schemaLocation="http://tempuri.org/getCustomer/ getCustomer_V200906.xsd" xmlns:mes-root="http://tempuri.org/getCustomer/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
 <mes-root:Result>
  <mes-root:ResultCode/>
  <mes-root:ErrorsList/>
 </mes-root:Result>
</mes-root:getResponse>

How can I accomplish this ? Do i need to set certain XML Serialization atttibutes on the getResponse class for the mes-root prefix to show up at the client end ?

EDIT: I found a similar question at the following location http://forums.asp.net/t/1249049.aspx. To be honest, I do not quite understand it and I am unable to get it to work.

+1  A: 

OK, the second sample is now valid XML, but it isn't semantically equivalent to the first sample, because the first one has two namespaces and the second one only has one.

Is the problem that you're sending XML that isn't semantically correct, or that they specifically require the prefix to be called mes-root?

Greg Beech
@Greg, I updated the output response with the ns declaration. But I am not sure how to go about generating the prefixes for the user.
Preets
Do I need to provide some serialization information for the getResponse class ?
Preets
Just updated my answer - your XML samples still aren't equivalent, so you should work out if that's the problem first!
Greg Beech
@Greg, unfortunately its the latter .. which is the content is correct, but the prefix is missing.. the test env at the client end is web methods. Ideally should they be dealing with this issue ?
Preets
Any standards compliant XML library shoudn't care what the prefix is (or even whether a prefix is used) as long as the contents are semantically equivalent. If you're sure the contents are equivalent, then I'd say it's the client's problem, not yours, and they need to sort their XML libraries!
Greg Beech
+4  A: 

Hi Preets,

In usual conditions, it is the client which must conform to the type of response that a Web service sends. Your case, however, appears to be different, since you appear to be building a Webservice that provides a pre-existing client a formatted response.

To solve the namespace prefix problem, the link you mentioned in your question provides an appropriate solution; You will need to "guide" the XmlSerializer during the serialization process and you can do this by specifying the XmlNamespaceDeclarations attribute to a property that returns an object of type XmlSerializerNamespaces. The property will need to be settable as well, or the namespaces will not be applied.

When you add the following code to your getResponse class, the xml response will as per expected format in your example:

[XmlNamespaceDeclarations()] 
public XmlSerializerNamespaces xmlsn 
{ 
  get 
  { 
    XmlSerializerNamespaces xsn = new XmlSerializerNamespaces(); 
    xsn.Add("mes-root", "http://tempuri.org/getCustomer/"); 
    return xsn; 
  } 
  set 
  {
  //Just provide an empty setter. 
  } 
}

Analzing the WSDL class generated for such a webservice reveals the following method ("GetMyResponse" is the name I gave to the WS method that returns a GetResponse object):

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/getCustomer/GetMyResponse", RequestNamespace = "http://tempuri.org/getCustomer/", ResponseNamespace = "http://tempuri.org/getCustomer/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 
public GetResponse GetMyResponse() 
{ 
  object[] results = this.Invoke("GetMyResponse", new object[-1 + 1]); 
  return (GetResponse)results(0); 
}

I believe that the RequestNamespace and ResponseNamespace attributes which make a difference.

Hope this clears up a few issues in understanding the underlying Xml Serialization that's taking place here.

Edit (after comments)


Here is the response I received via my Test webservice:

<?xml version="1.0" encoding="utf-8"?>
<mes-root:GetResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:mes-root="http://tempuri.org/getCustomer/"&gt;
  <mes-root:Result>OK</mes-root:Result>
  <mes-root:ErrorsList>
    <mes-root:string>SomeErrors</mes-root:string>
    <mes-root:string>SomeMoreErrors</mes-root:string>
  </mes-root:ErrorsList>
</mes-root:GetResponse>
Cerebrus
@Cerebrus, Thank you for your response. It did work with the "XmlNamespaceDeclarations", however for some reason it works only if XmlSerializerNamespaces is initialized at the time of class creation. Rather wierd. However, is it was possible to prefix the root element GetResponse, with "mes-root"?
Preets
@Preets: I had created a basic sample to test out this scenario before answering. It did not require initialization of the XmlSerializerNamespaces at all. Also, the WS returned a result where the mes:root prefix was prepended to all elements, inclusive of the root element.
Cerebrus
@Cerebrus, which version of .net are you using ?
Preets
.NET 2.0, VS 2005. You?
Cerebrus
I was working with VS2003 .NET 1.1 / I shall try with VS 2008 .Net 3.5 and see if it makes a difference !
Preets
Cerebrus, I tried a very simple HelloWorld web service in 3.5 and the response is the following (pls. see next comment)
Preets
<HelloWorldResult xmlns:mes-root="http://tempuri.org/getCustomer/"> <mes-root:MyProperty>MyProp</mes-root:MyProperty></HelloWorldResult>
Preets
@Preets: I don't think we'll be able to reach a satisfactory solution via commenting. I'd suggest sending me an email if this is really important. You can find my email if you do a little investigation via my profile. (Not posting my email here... I'm spam-phobic ;-))
Cerebrus
Edited post to include the WS response I receive.
Cerebrus
@Cerebrus, Todays my lucky day ! I migrated the code to 3.5 and voila ! It works like a charm ! I guess the issue is only with the .net framework 1.1 ! Thanks a lot for your response ! Helped me move in the right direction!
Preets
Congratulations, Preets! And welcome to the "Lucky Day" club! Glad to help out. :P
Cerebrus
Just came across this (again) and has helped me solve a massive problem.Thanks :)
ck