【问题标题】:Add constraint on a field on deserializeion在反序列化的字段上添加约束
【发布时间】:2015-03-16 08:55:41
【问题描述】:

在 xsd 架构中,我将属性 ID 定义为

<xs:attribute name="ID" type="xs:nonNegativeInteger" use="required"/>

但是,即使 ID 设置为大于 UInt32.MaxValue 的值,xml 对 xsd 架构的验证也会通过。

我的反序列化代码如下:

var ser = new XmlSerializer(typeof(MyClass));
var settings = new XmlReaderSettings();
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ProcessSchemaLocation | XmlSchemaValidationFlags.ProcessIdentityConstraints |    XmlSchemaValidationFlags.AllowXmlAttributes;
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(_schemaNs, _schemaFileName);

var tReader = XmlReader.Create(filename, settings);
try
{
      var obj = ser.Deserialize(tReader) as MyClass;
}
catch(Excetion e)
{/*Process Validation exception.*/}

上面定义了相应的变量。

MyClass的定义中我有:

    private uint idField;
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public uint ID
    {

        get
        {               
            return this.idField;
        }
        set
        {
            this.idField = value;
        }
    }

现在,如果 ID 的值设置为太大的数字,我希望 XmlSerializer 引发异常。我想到的第一个想法是将MyClass中的ID字段类型设置为string并自己进行验证。但是,似乎有一种更优雅的方法可以做到这一点。

【问题讨论】:

    标签: c# xml xml-deserialization


    【解决方案1】:

    我建议不要将过滤不需要的值的逻辑编码到反序列化中,而是编码到setter本身中,可以如下完成。

    private uint idField;
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public uint ID
    {
        get
        {               
            return this.idField;
        }
        set
        {
            int SOME_BOUND = 10000;
            if (value > SOME_BOUND)
            {
                throw new ApplicationException();
            }
            this.idField = value;
        }
    }
    

    ApplicationException 类记录在 here 中。 ArgumentOurOfBoundsException 也可能合适。

    【讨论】:

      【解决方案2】:

      或许您可以通过这种方式在 XSD Schema 中指定它:

      <xs:attribute name="ID" use="required">
          <xs:simpleType>
              <xs:restriction base="xs:integer">
                  <xs:minInclusive value="0"/>
                  <xs:maxInclusive value="4294967295"/>
              </xs:restriction>
          </xs:simpleType>
      </xs:attribute>
      

      以下SO post 也可能有帮助。

      【讨论】:

        猜你喜欢
        • 2023-01-19
        • 2018-05-28
        • 1970-01-01
        • 1970-01-01
        • 2020-06-29
        • 1970-01-01
        • 2014-01-06
        • 2015-05-19
        • 2016-04-05
        相关资源
        最近更新 更多