3

所以我有以下方法:

private int? myIntField
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int? IntField{
    get {
        return this.myIntField;
    }
    set {
        this.myIntField= value;
    }
 }

现在,我正在反序列化帖子中的 xml,如果出于某种原因我得到一个字符串,例如“这里是 int 字段:55444”而不是 55444,我得到的响应错误是:Input string was not in a correct format.这不是很具体,特别是考虑到我需要验证的 int 字段不止一个。

最初,我计划这样的事情:

private string myIntField
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int? IntField{
    get {
        return this.myIntField.CheckValue();
    }
    set {
        this.myIntField= value;
    }
 }

CheckValuetry-parse对 Int32 执行 a 的位置,如果失败,则返回 null 并将错误添加到列表中。但是,我似乎无法为生成的类确定此设置。

如果我用字符串代替整数、日期时间等,是否有办法抛出特定错误?

4

3 回答 3

4

如果您有 XML 模式并在反序列化之前根据模式验证它,这很容易。假设您有 XML 架构,您可以初始化 XmlSchemaSet,在其中添加架构,然后:

var document = new XmlDocument();
document.LoadXml(xml); // this a string holding the XML
document.Schemas.XmlResolver = null; //if you don't need to resolve every references
document.Schemas.Add(SchemaSet); // System.Xml.Schema.XmlSchemaSet instance filled with schemas
document.Validate((sender, args) => { ... }); //args are of type ValidationEventArgs and hold problem if there is one...            

我个人认为这是一种更好的方法,因为您可以在反序列化之前验证您的 XML 并确保 XML 是正确的,否则反序列化程序很可能会在出现问题时抛出异常,并且您几乎永远无法向用户...
PS 我建议创建描述 XML 的模式

于 2012-05-09T21:48:35.203 回答
3

“输入字符串的格式不正确”消息来自System.FormatException调用引发的标准int.Parse,添加到执行反序列化的自动生成的程序集中。我认为您不能为此添加一些自定义逻辑。

一种解决方案是执行以下操作:

    [XmlElement("IntField")]
    [Browsable(false)] // not displayed in grids
    [EditorBrowsable(EditorBrowsableState.Never)] // not displayed by intellisense
    public string IntFieldString
    {
        get
        {
            return DoSomeConvert(IntField);
        }
        set
        {
            IntField = DoSomeOtherConvert(value);
        }
    }

    [XmlIgnore]
    public int? IntField { get; set; }

这并不完美,因为您仍然可以访问 public IntFieldString,但至少,“真实”IntField属性仅以编程方式使用,而不是由 XmlSerializer ( XmlIgnore) 使用,而来回保存值的字段对程序员是隐藏的( EditorBrowsable)、网格 ( Browsable) 等...但不是来自XmlSerializer.

于 2012-05-10T12:34:19.103 回答
2

我为您提供了三种方法。

  • 假设您的数据是由用户在用户界面中输入的,请使用输入验证来确保数据有效。当它应该是一个整数时允许输入随机字符串似乎很奇怪。

  • 完全使用您上面建议的方法。这是使用 LINQ Pad 的示例

    void Main()
    {
        using(var stream = new StringReader(
                  "<Items><Item><IntValue>1</IntValue></Item></Items>"))
        {
            var serializer = new XmlSerializer(typeof(Container));
    
            var items = (Container)serializer.Deserialize(stream);
    
            items.Dump();
        }
    }
    
    [XmlRoot("Items")]
    public class Container
    {
        [XmlElement("Item")]
        public List<Item> Items { get; set; }
    }
    
    public class Item
    {
        [XmlElement("IntValue")]
        public string _IntValue{get;set;}
    
        [XmlIgnore]
        public int IntValue
        {
            get
            {
                // TODO: check and throw appropriate exception
                return Int32.Parse(_IntValue);
            }
        }
    }
    
  • 使用 IXmlSerializable 控制序列化,这是另一个示例

    void Main()
    {
        using(var stream = new StringReader(
                  "<Items><Item><IntValue>1</IntValue></Item></Items>"))
        {
            var serializer = new XmlSerializer(typeof(Container));
    
            var items = (Container)serializer.Deserialize(stream);
    
            items.Dump();
        }
    }
    
    [XmlRoot("Items")]
    public class Container
    {
        [XmlElement("Item")]
        public List<Item> Items { get; set; }
    }
    
    public class Item : IXmlSerializable
    {
        public int IntValue{get;set;}
    
        public void WriteXml (XmlWriter writer)
        {
            writer.WriteElementString("IntValue", IntValue.ToString());
        }
    
        public void ReadXml (XmlReader reader)
        {
            var v = reader.ReadElementString();
            // TODO: check and throw appropriate exception
            IntValue = int.Parse(v);
        }
    
        public XmlSchema GetSchema()
        {
            return(null);
        }
    }
    
于 2012-05-10T09:31:23.380 回答