如果找不到元素,我能否在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:18:16  来源:igfitidea点击:

Can I fail to deserialize with XmlSerializer in C# if an element is not found?

c#xmlxml-serialization.net-attributes

提问by Alex B

I am using XmlSerializer to write and read an object to xml in C#. I currently use the attributes XmlElementand XmlIgnoreto manipulate the serialization of the object.

我正在使用 XmlSerializer 在 C# 中将对象写入和读取到 xml。我目前使用属性XmlElementXmlIgnore操作对象的序列化。

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 XmlRequiredattribute.

我理想的解决方案是添加类似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, XmlSerializeris very forgiving when it comes to deserialization; things like [DefaultValue], ShouldSerialize{Foo}and {Foo}Specifiedare 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 IXmlSerializableand do it yourself. damagednoob shows an xsd option, which is also an option.

像这样; 没有一种简单的方法可以做到这一点,除非您IXmlSerializable自己实施并做到这一点。损坏的noob 显示了一个 xsd 选项,这也是一个选项。