如果找不到元素,我能否在 C# 中使用 XmlSerializer 进行反序列化失败?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/259726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I fail to deserialize with XmlSerializer in C# if an element is not found?
提问by Alex B
I am using XmlSerializer to write and read an object to xml in C#. I currently use the attributes XmlElement
and XmlIgnore
to manipulate the serialization of the object.
我正在使用 XmlSerializer 在 C# 中将对象写入和读取到 xml。我目前使用属性XmlElement
并XmlIgnore
操作对象的序列化。
If my xml file is missing an xml element that I require, my object still deserializes (xml -> object) just fine. How do I indicate (preferably via Attributes) that a certain field is "required"?
如果我的 xml 文件缺少我需要的 xml 元素,我的对象仍然可以很好地反序列化 (xml -> object)。我如何指示(最好通过属性)某个字段是“必需的”?
Here is a sample method of what I am using currently:
这是我目前使用的示例方法:
[XmlElement(ElementName="numberOfWidgets")]
public int NumberThatIsRequired {
set ...;
get ...;
}
My ideal solution would be to add something like an XmlRequired
attribute.
我理想的解决方案是添加类似XmlRequired
属性的东西。
Also, is there a good reference for what Attributes are available to manipulate the behavior of XmlSerializer?
另外,对于可用于操纵 XmlSerializer 行为的属性是否有很好的参考?
采纳答案by Jon Skeet
I've got an answer for the second part: "Attributes that control XML serialization".
我得到了第二部分的答案:“控制 XML 序列化的属性”。
Still investigating the first part...
还在研究第一部分……
EDIT: I strongly suspect you can't do this through XML deserialization itself. I've just run xsd.exe on a sample schema which includes a required attribute - and it's exactly the same if the attribute is marked as being optional. If there were a way of requiring properties to be set, I'd expect it to be implemented in that case.
编辑:我强烈怀疑你不能通过 XML 反序列化本身来做到这一点。我刚刚在包含必需属性的示例架构上运行 xsd.exe - 如果该属性被标记为可选,则完全相同。如果有一种方法需要设置属性,我希望在这种情况下实现它。
I suspect you've basically got to just validate your tree of objects after deserializing it. Sorry about that...
我怀疑您基本上必须在反序列化后验证您的对象树。对于那个很抱歉...
回答by Richard Nienaber
The only way I've found to do this is via XSD. What you can do is validate while you deserialize:
我发现这样做的唯一方法是通过 XSD。您可以做的是在反序列化时进行验证:
static T Deserialize<T>(string xml, XmlSchemaSet schemas)
{
//List<XmlSchemaException> exceptions = new List<XmlSchemaException>();
ValidationEventHandler validationHandler = (s, e) =>
{
//you could alternatively catch all the exceptions
//exceptions.Add(e.Exception);
throw e.Exception;
};
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(schemas);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += validationHandler;
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xml))
using (XmlReader books = XmlReader.Create(sr, settings))
return (T)serializer.Deserialize(books);
}
回答by Marc Gravell
For extensibility reasons, XmlSerializer
is very forgiving when it comes to deserialization; things like [DefaultValue]
, ShouldSerialize{Foo}
and {Foo}Specified
are mainlyused during serialization(the exception being {Foo}Specified
, which is set during deserialization as well as queried during serialization).
出于可扩展性的原因,XmlSerializer
在反序列化方面非常宽容;像[DefaultValue]
,ShouldSerialize{Foo}
和 之{Foo}Specified
类的东西主要在序列化期间使用(例外是{Foo}Specified
,它在反序列化期间设置以及在序列化期间查询)。
As such; there isn't an easy way to do this, unless you implement IXmlSerializable
and do it yourself. damagednoob shows an xsd option, which is also an option.
像这样; 没有一种简单的方法可以做到这一点,除非您IXmlSerializable
自己实施并做到这一点。损坏的noob 显示了一个 xsd 选项,这也是一个选项。