Nullable类型在亚音速2.2中破坏了ToXML()

时间:2009-06-11 01:55:11

标签: asp.net subsonic

当我致电.ToXML()时,我收到了错误消息:

  

“反映类型的错误......”

我有一个可以为空的类型。我该如何解决?

1 个答案:

答案 0 :(得分:0)

Subsonic论坛有这个主题,有一个可能的解决方案:

http://forums.subsonicproject.com/forums/t/334.aspx

    #region Overridden XML Serialization Logic

    public override object NewFromXML(string xml)
    {
        System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
        xdoc.LoadXml(xml);
        object lObject = base.NewFromXML(xml);
        PropertyInfo[] propertyInfos = lObject.GetType().GetProperties();
        foreach (PropertyInfo propertyInfo in propertyInfos)
        {
            if (propertyInfo == null)
                continue;
            if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))                
            {
                if (xdoc.DocumentElement.Attributes[propertyInfo.Name] == null)
                    continue;
                string textValue = xdoc.DocumentElement.Attributes[propertyInfo.Name].Value;
                Type[] typeArgs = propertyInfo.PropertyType.GetGenericArguments();
                if (typeArgs == null || typeArgs.Length == 0)
                    continue;
                object typedValue = GetTypedValue(textValue, typeArgs[0]);
                propertyInfo.SetValue(lObject, typedValue, null);
            }
        }
        return lObject;
    }

    private object GetTypedValue(string textValue, Type type)
    {
        if (string.IsNullOrEmpty(textValue))
            return null;
        object typedValue = null;
        if (type == typeof(DateTime))
            typedValue = Convert.ToDateTime(textValue);
        else if (type == typeof(Byte))
            typedValue = Convert.ToByte(textValue);
        else if (type == typeof(Int16))
            typedValue = Convert.ToInt16(textValue);
        else if (type == typeof(Int32))
            typedValue = Convert.ToInt32(textValue);
        else if (type == typeof(Int64))
            typedValue = Convert.ToUInt64(textValue);
        else if (type == typeof(Double))
            typedValue = Convert.ToDouble(textValue);
        else if (type == typeof(Single))
            typedValue = Convert.ToSingle(textValue);
        else if (type == typeof(Boolean))
            typedValue = Convert.ToBoolean(textValue);
        else if (type == typeof(Guid))
            typedValue = new Guid(textValue);
        else
            throw new NotImplementedException(string.Format("Conversion of type {0} from a string to a typed value is not implemented, yet. TextValue: {1}", type, textValue));
        return typedValue;
    }


    public override string ToXML()
    {
        string xml = base.ToXML();
        System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
        xdoc.LoadXml(xml);
        PropertyInfo[] propertyInfos = this.GetType().GetProperties();
        foreach (PropertyInfo propertyInfo in propertyInfos)
        {
            if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                object val = propertyInfo.GetValue(this, null);
                if (val == null)
                    continue;
                XmlAttribute attribute = xdoc.CreateAttribute(propertyInfo.Name);
                attribute.Value = val.ToString();
                xdoc.DocumentElement.Attributes.Append(attribute);
                Console.WriteLine(propertyInfo.Name);
            }
        }

        return xdoc.DocumentElement.OuterXml;
    }        

    #endregion