如果未找到元素,C# 中的 XmlSerializer 反序列化是否会失败?

发布于 2024-07-09 07:26:18 字数 480 浏览 9 评论 0原文

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

如果我的 xml 文件缺少我需要的 xml 元素,我的对象仍然可以很好地反序列化(xml -> object)。 如何指示(最好通过属性)某个字段是“必填”?

以下是我当前使用的示例方法:

[XmlElement(ElementName="numberOfWidgets")]
public int NumberThatIsRequired {
    set ...;
    get ...;
}

我理想的解决方案是添加诸如 XmlRequired 属性之类的内容。

另外,对于哪些属性可用于操纵 XmlSerializer 的行为,是否有一个很好的参考?

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.

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"?

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.

Also, is there a good reference for what Attributes are available to manipulate the behavior of XmlSerializer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-残月青衣踏尘吟 2024-07-16 07:26:18

我发现做到这一点的唯一方法是通过 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);
}

The only way I've found to do this is via XSD. What you can do is validate while you deserialize:

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);
}
挖鼻大婶 2024-07-16 07:26:18

我有第二部分的答案: "Attributes控制 XML 序列化”

仍在调查第一部分...

编辑:我强烈怀疑您无法通过 XML 反序列化本身来做到这一点。 我刚刚在包含必需属性的示例架构上运行 xsd.exe - 如果该属性被标记为可选,则效果完全相同。 如果有一种方法要求设置属性,我希望它能够在这种情况下实现。

我怀疑您基本上必须在反序列化后验证您的对象树。 对于那个很抱歉...

I've got an answer for the second part: "Attributes that control XML serialization".

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.

I suspect you've basically got to just validate your tree of objects after deserializing it. Sorry about that...

倦话 2024-07-16 07:26:18

出于可扩展性的原因,XmlSerializer 在反序列化方面非常宽容; [DefaultValue]ShouldSerialize{Foo}{Foo}Specified 等内容主要期间使用序列化(例外是{Foo}Specified,它在反序列化期间设置并在序列化期间查询)。

像这样; 没有简单的方法可以做到这一点,除非您实现 IXmlSerialized 并自己完成。 Richard展示了一个xsd选项,这也是一个选项。

For extensibility reasons, XmlSerializer is very forgiving when it comes to deserialization; things like [DefaultValue], ShouldSerialize{Foo} and {Foo}Specified are mainly used during serialization (the exception being {Foo}Specified, which is set during deserialization as well as queried during serialization).

As such; there isn't an easy way to do this, unless you implement IXmlSerializable and do it yourself. Richard shows an xsd option, which is also an option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文