在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
并自行执行验证。然而,似乎有更优雅的方式来做到这一点。
答案 0 :(得分:1)
我建议将不需要的值过滤的逻辑编码到反序列化中,而不是编码器本身,这可以按如下方式完成。
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也可能适用。
答案 1 :(得分:1)
您可以通过这种方式在XSD架构中指定它:
<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也可能会有所帮助。