In one of my project I was consuming an web service which had some Inheritance where the parent Class is EmployeeProfile and the child Class is FieldEmployeeProfile. When I was calling a method returning Child Class object Array, I was not getting the Child Class specific Properties (not those inherited from Parent) set. Instead, I found a property in Parent Class called "Any' which is an Array of XMLElement and having the missing Child Object Property equivalent Name-Values in the XML element array.
I will try to explain the problem using a simpler example I created and the resolution.
Server Side Classes
The WSDL generated for these classes as as below
</s:complexType>
When my web method returns Rectangle I get it as below with Side1 and Side2 property values as 0 and the base Any Property is having those missing property related XMLElements.
To fix this the easiest way is to remove the "Any" property related code from the Base Class shape in "Reference.Cs" file as below (you need to click on "Show All Files" in Solution explorer top to show Reference.cs file in solution explorer).
The alternate approach is to update the reference.cs file for the code generated for child class Rectangle as below:
I will try to explain the problem using a simpler example I created and the resolution.
Server Side Classes
public class Shape
{
//[System.Xml.Serialization.XmlTypeAttribute("Name")]
[System.Xml.Serialization.XmlElement(Order = 0)]
public string Name { get; set; }
[System.Xml.Serialization.XmlElement(Order = 1)]
public virtual int Area { get; set; }
[System.Xml.Serialization.XmlAnyElementAttribute(Order = 2)]
public
System.Xml.XmlElement[] AnyElement
{
get;
set;
}
}
public class
Rectangle : Shape
{
[System.Xml.Serialization.XmlElement(Order = 0)]
public int Side1 { get; set; }
[System.Xml.Serialization.XmlElement(Order = 1)]
public int Side2 { get; set; }
[System.Xml.Serialization.XmlElement(Order = 2)]
public override int Area
{
get
{
return
Side1 * Side2;
}
}
[System.Xml.Serialization.XmlAnyElement(Order = 3)]
public
System.Xml.XmlElement[] AnyChildElement
{
get;
set;
}
}
Note the AnyElement in Parent Class and special attention to Order value. I will explain it later.
<s:complexType
name="Shape">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="Area" type="s:int" />
<s:any minOccurs="0" maxOccurs="unbounded" />
</s:sequence>
</s:complexType>
<s:complexType
name="Rectangle">
<s:complexContent mixed="false">
<s:extension base="tns:Shape">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Side1" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Side2" type="s:int" />
<s:any minOccurs="0" maxOccurs="unbounded" />
</s:sequence>
</s:extension>
</s:complexContent>
To fix this the easiest way is to remove the "Any" property related code from the Base Class shape in "Reference.Cs" file as below (you need to click on "Show All Files" in Solution explorer top to show Reference.cs file in solution explorer).
The alternate approach is to update the reference.cs file for the code generated for child class Rectangle as below:
[System.Xml.Serialization.XmlElementAttribute(Order = 0)]
public int Side1
{
get
{
if (this.side1Field == 0)
{
foreach (System.Xml.XmlElement
xe in base.Any)
{
if (xe.Name == "Side1")
{
int.TryParse(xe.InnerText, out
this.side1Field);
}
}
}
return
this.side1Field;
}
set
{
this.side1Field
= value;
}
}
///
[System.Xml.Serialization.XmlElementAttribute(Order = 1)]
public int Side2
{
get
{
if (this.side2Field == 0)
{
foreach (System.Xml.XmlElement
xe in base.Any)
{
if (xe.Name == "Side2")
{
int.TryParse(xe.InnerText, out
this.side2Field);
}
}
}
return
this.side2Field;
}
set
{
this.side2Field
= value;
}
}
Note the tag is for expending the request & response payload for an web service in future without changing the WSDL. So you may require to actually utilize the Any property. So you shouldn't delete the property from reference.cs file if your code needs to handle any additional node without breaking it's logic.
I previously mentioned to pay special attention to Order value in the server side code for the classes. The reason is that all the properties following the Any element, will not be populated if you are not taking special care. It will have same null/0 value as the Child class properties.
No comments:
Post a Comment