public override object ConvertXmlToObject(XmlReader xmlReader, XmlRootAttribute xmlAttrib)
{
object?retValue = null;
bool isBaseCLRType = false;
bool legacyUDT = false; // in 1.0 and 1.1 we used to call ToString on CDT obj. so if we have the same case
// we need to handle the case when we have column type as object.
if (null == xmlAttrib)
{ // this means type implements IXmlSerializable
Type? type = null;
string?typeName = xmlReader.GetAttribute(Keywords.MSD_INSTANCETYPE, Keywords.MSDNS);
if (typeName == null || typeName.Length == 0)
{ // No CDT polumorphism
string?xsdTypeName = xmlReader.GetAttribute(Keywords.TYPE, Keywords.XSINS); // this xsd type: Base type polymorphism
if (null != xsdTypeName && xsdTypeName.Length > 0)
{
string[] _typename = xsdTypeName.Split(':');
if (_typename.Length == 2)
{ // split will return aray of size 1 if ":" is not there
if (xmlReader.LookupNamespace(_typename[0]) == Keywords.XSDNS)
{
xsdTypeName = _typename[1]; // trim the prefix and just continue with
}
} // for other case, let say we have two ':' in type, the we throws (as old behavior)
type = XSDSchema.XsdtoClr(xsdTypeName);
isBaseCLRType = true;
}
else if (_dataType == typeof(object))
{ // there is no Keywords.MSD_INSTANCETYPE and no Keywords.TYPE
legacyUDT = true; // see if our type is object
}
}
if (legacyUDT)
{ // if Everett UDT, just read it and return string
retValue = xmlReader.ReadString();
}
else
{
if (typeName == Keywords.TYPEINSTANCE)
{
retValue = Type.GetType(xmlReader.ReadString());
xmlReader.Read(); // need to move to next node
}
else
{
if (null == type)
{
type = (typeName == null) ? _dataType : DataStorage.GetType(typeName);
}
if (type == typeof(char) || type == typeof(Guid))
{ //msdata:char and msdata:guid imply base types.
isBaseCLRType = true;
}
if (type == typeof(object))
{
throw ExceptionBuilder.CanNotDeserializeObjectType();
}
TypeLimiter.EnsureTypeIsAllowed(type);
if (!isBaseCLRType)
{
retValue = System.Activator.CreateInstance(type, true) !;
Debug.Assert(xmlReader is DataTextReader, "Invalid DataTextReader is being passed to customer");
((IXmlSerializable)retValue).ReadXml(xmlReader);
}
else
{ // Process Base CLR type
// for Element Node, if it is Empty, ReadString does not move to End Element; we need to move it
if (type == typeof(string) && xmlReader.NodeType == XmlNodeType.Element && xmlReader.IsEmptyElement)
{
retValue = string.Empty;
}
else
{
retValue = xmlReader.ReadString();
if (type != typeof(byte[]))
{
retValue = SqlConvert.ChangeTypeForXML(retValue, type);
}
else
{
retValue = Convert.FromBase64String(retValue.ToString() !);
}
}
xmlReader.Read();
}
}
}
}
else
{
XmlSerializer deserializerWithRootAttribute = ObjectStorage.GetXmlSerializer(_dataType, xmlAttrib);
retValue = deserializerWithRootAttribute.Deserialize(xmlReader);
}
return(retValue !);
}