Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#xml序列化必填字段_C#_.net_Xml_Serialization_Xml Serialization - Fatal编程技术网

C#xml序列化必填字段

C#xml序列化必填字段,c#,.net,xml,serialization,xml-serialization,C#,.net,Xml,Serialization,Xml Serialization,我需要将一些字段标记为需要在XML文件中写入的字段,但没有成功。我有一个大约30个属性的配置类,这就是为什么我不能像这样封装所有属性 public string SomeProp { get { return _someProp; } set { if (_someProp == null) throw new ArgumentNullException("value");

我需要将一些字段标记为需要在XML文件中写入的字段,但没有成功。我有一个大约30个属性的配置类,这就是为什么我不能像这样封装所有属性

    public string SomeProp
    {
        get { return _someProp; }
        set
        {
            if (_someProp == null)
                throw  new ArgumentNullException("value");
            _someProp = value;
        }
    }
null是代码中的有效值,但不是XML中的有效值。我试图使用
xmltattribute
,但它并没有像我预期的那样产生影响(反序列化时出现IOException)

例如,此代码:

    [XmlElement(IsNullable = true)]
    public String Name { get; set; }

    [XmlElement(IsNullable = true)]
    public String Description { get; set; }
当缺少
Name
Description
标记时,此选项非常有效


澄清:

类别:

public class MyClass
{
    [XmlElement(IsNullable = true)]
    public String Name { get; set; }

    [XmlElement(IsNullable = true)]
    public String Description { get; set; } 
}
XML:

结果:
反序列化成功,说明为空


应为:
异常,未找到描述标记。
我相信您可以遵循两种方法。一个是使用使用模式的验证XmlReader,另一个是反序列化后的反射检查。最后一个选项是我在这里提供的解决方案:

此助手获取一个流,并将给定泛型类型的流反序列化为该类型的实例。一旦该对象存在,就可以迭代并检查其属性是否使用XmlElementAttribute修饰。如果找到该属性,则会检查其IsNullable属性,如果为false且对象实例上的属性为false,则会引发异常

public T ValidatingDeserializer<T>(Stream s)
{
    T deserialize = (T)new XmlSerializer( typeof(T)).Deserialize(s);

    foreach(var pi in typeof(T).GetProperties())
    {
        var xmlnull = pi.GetCustomAttribute(typeof(XmlElementAttribute));
        if (xmlnull!=null)
        {   var xmlnullInst = (XmlElementAttribute) xmlnull;
            if (!xmlnullInst.IsNullable && pi.GetValue(deserialize)==null)
            {
                throw new Exception(String.Format("{0} is null", pi.Name));
            }
        }
    }
    return deserialize;
}
ValidateEvent目标 已使用问题中显示的xml的示例架构
您必须使用
XmlSerializer
DataContractSerializer
提供以下选项:

[DataMember(IsRequired = true)]

当遇到空值时,您能否澄清何时要抛出。在序列化或反序列化过程中?这很好,但它应该以递归方式工作。因此,应检查所有字段的所有属性和属性等。这就是为什么我希望实现序列化的标准化。因为我可以手动检查所有内容,但这会花费我很多钱,而且这些类的属性也会被修饰?当然。我知道我们可以检查所有道具,但这么多的反射对我来说太糟糕了。为什么?这是时间/资源关键路径吗?我只是不喜欢反思。但是现在你的答案是最好的。所以我做了标记,tnx。不幸的是,您不能用数据协定序列化程序将属性修饰为属性,所以我不能使用它。必须保留XMLSerializer,但仍然存在问题。
public T ValidatingDeserializer<T>(Stream s)
{
    T deserialize = (T)new XmlSerializer( typeof(T)).Deserialize(s);

    foreach(var pi in typeof(T).GetProperties())
    {
        var xmlnull = pi.GetCustomAttribute(typeof(XmlElementAttribute));
        if (xmlnull!=null)
        {   var xmlnullInst = (XmlElementAttribute) xmlnull;
            if (!xmlnullInst.IsNullable && pi.GetValue(deserialize)==null)
            {
                throw new Exception(String.Format("{0} is null", pi.Name));
            }
        }
    }
    return deserialize;
}
MyClass deserialize = ValidatingDeserializer<MyClass>(
     new FileStream("result.xml", FileMode.Open));

Console.WriteLine(deserialize.Name);
Console.WriteLine(deserialize.Description);
public XmlReader ReaderFactory(Stream xml, Stream schema)
{
    XmlSchemaSet sc = new XmlSchemaSet();

    // Add the schema to the collection.
    sc.Add(null, XmlReader.Create(schema));

    // Set the validation settings.
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;

    settings.Schemas = sc;
    settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

    return XmlReader.Create(xml, settings);
}
 private static void ValidationCallBack(object sender, ValidationEventArgs e) {
    Console.WriteLine(
        "Validation Error: {0} near line: {1}, pos: {2}", 
        e.Message, 
        e.Exception.LineNumber, 
        e.Exception.LinePosition);
    throw new Exception("illegal xml content");
  }
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns=""
            elementFormDefault="qualified">

    <xsd:element name="MyClass" >
        <xsd:complexType>
            <xsd:sequence maxOccurs="1">
                <xsd:element name="Name" type="xsd:string"/>
                <xsd:element name="Description" type="xsd:string" minOccurs="1">
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>
[DataMember(IsRequired = true)]