.NET,我为什么非要用*指定属性,迫使序列化?有没有办法不这样做?

问题描述 投票:17回答:5

我用我的项目XML序列化序列化和反序列化基于XML架构对象。我使用的XSD工具来创建类序列化/反序列化对象时使用。

当我去之前发送序列化对象,我不得不设置*指定属性设置为true,以迫使串行序列化,并且是类型qazxsw POI的并不是所有的属性。

有没有办法强制所有属性的序列,而无需在*指定属性设置为true?

c# .net xsd xml-serialization
5个回答
21
投票

string属性用于控制FooSpecified属性是否必须序列化。如果你总是想要序列化的属性,只是删除Foo财产。


5
投票

我知道这是一个老问题,但没有其他答案(除使用Xsd2Code也许建议)确实会产生当你生成的代码作为构建的一部分的理想解决方案和您的.xsd可以在一个单一的多次更改发布周期。

对我来说一个简单的方法来得到我真正想要的,并仍然使用XSD.EXE是通过运行一个简单的处理器后生成的文件。对于后处理器的代码如下:

FooSpecified

结果产生类似于以下代码:

namespace XsdAutoSpecify
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            if (args.Length != 1)
            {
                throw new ArgumentException("Specify a file name");
            }

            string fileName = args[0];
            Regex regex = new Regex(".*private bool (?<fieldName>.*)Specified;");

            IList<string> result = new List<string>();
            IDictionary<string, string> edits = new Dictionary<string, string>();

            foreach (string line in File.ReadLines(fileName))
            {
                result.Add(line);
                if (line.Contains("public partial class"))
                {
                    // Don't pollute other classes which may contain like-named fields
                    edits.Clear();
                }
                else if (regex.IsMatch(line))
                {
                    // We found a "private bool fooSpecified;" line.  Add
                    // an entry to our edit dictionary.
                    string fieldName = regex.Match(line).Groups["fieldName"].Value;
                    string lineToAppend = string.Format("this.{0} = value;", fieldName);
                    string newLine = string.Format("                this.{0}Specified = true;", fieldName);
                    edits[lineToAppend] = newLine;
                }
                else if (edits.ContainsKey(line.Trim()))
                {
                    // Use our edit dictionary to add an autospecifier to the foo setter, as follows:
                    //   set {
                    //       this.fooField = value;
                    //       this.fooFieldSpecified = true;
                    //   }
                    result.Add(edits[line.Trim()]);
                }
            }

            // Overwrite the result
            File.WriteAllLines(fileName, result);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
            Environment.Exit(-1);
        }
    }
}
}

2
投票

我面临着同样的问题,并最终通过反射将所有*指定属性为true。

喜欢

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public barEnum foo {
        get {
            return this.fooField;
        }
        set {
            this.fooField = value;
            this.fooFieldSpecified = true;
        }
    }

1
投票

你可以默认值添加到您的模式,然后使用var customer = new Customer(); foreach (var propertyInfo in typeof(Customer).GetProperties().Where(p => p.Name.EndsWith("Specified"))) { propertyInfo.SetValue(customer, true); }

例如,你可以在你的架构如下:

DefaultValueAttribute

然后将下面的属性进行序列化:

<xs:element name="color" type="xs:string" default="red"/>

这应该强制色彩属性始终序列为“红色”,如果它没有明确设置为别的东西。


1
投票

我们发现,这个问题的答案是确保架构元素都被定义为[DefaultValue(red)] public string color { get; set; } 数据类型。这将确保串行序列化的所有字段不使用相关*指定属性。

© www.soinside.com 2019 - 2024. All rights reserved.