gpt4 book ai didi

c# - : "You need to add XmlChoiceIdentifierAttribute to the member." when using XmlAttributeOverrides?如何解决

转载 作者:行者123 更新时间:2023-11-30 22:56:27 25 4
gpt4 key购买 nike

我正在尝试使用 XmlAttributeOverrides 来更改我的类序列化为 XML 的方式。我需要排除一些属性并按特定顺序包含其他属性。

我这里有这段代码:

// XML Attribute Overrrides
public static XmlAttributeOverrides GetXMLAttributeOverrides(Type theType, List<string> propertiesToInlcudeInOrder, List<string> allColumnNames)
{
try
{
if (propertiesToInlcudeInOrder != null)
{
XmlAttributeOverrides theXMLAttributeOverrides = new XmlAttributeOverrides();
if (propertiesToInlcudeInOrder.Count > 0)
{
XmlAttributes mainNewXMLAttributes = new XmlAttributes();
mainNewXMLAttributes.XmlIgnore = false;

XmlAttributes ignoreXMLAttributes = new XmlAttributes();
ignoreXMLAttributes.XmlIgnore = true;

List<string> propertiesToNotInclude = new List<string>();
foreach (string theColumnName in allColumnNames)
{
string thePropertyName = theColumnName;
bool addProperty = true;
foreach (string propertyToInclude in propertiesToInlcudeInOrder)
{
if (thePropertyName == propertyToInclude)
{
addProperty = false;
break;
}
}

if (addProperty)
{
propertiesToNotInclude.Add(thePropertyName);
}
}

// To Ignore
foreach (string propertyNameToNotInlcude in propertiesToNotInclude)
{
XmlElementAttribute theXMLElementAttributeToAdd = new XmlElementAttribute(propertyNameToNotInlcude);
theXMLElementAttributeToAdd.ElementName = propertyNameToNotInlcude;
ignoreXMLAttributes.XmlElements.Add(theXMLElementAttributeToAdd);

theXMLAttributeOverrides.Add(theType, propertyNameToNotInlcude, ignoreXMLAttributes);
}

// To Add In Order
int counter = 1;
foreach (string propertyNameToIncludeInOrder in propertiesToInlcudeInOrder)
{
XmlElementAttribute theXMLElementAttributeToAdd = new XmlElementAttribute(propertyNameToIncludeInOrder);
theXMLElementAttributeToAdd.ElementName = propertyNameToIncludeInOrder;
theXMLElementAttributeToAdd.Order = counter;
mainNewXMLAttributes.XmlElements.Add(theXMLElementAttributeToAdd);

theXMLAttributeOverrides.Add(theType, propertyNameToIncludeInOrder, mainNewXMLAttributes);

counter++;
}
}

return theXMLAttributeOverrides;
}
else
{
return null;
}
}
catch (Exception ex)
{
MessageBox.Show("Error at 'GetXMLAttributeOverrides'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}

在我的测试中,我有一个包含 13 个属性的类,我想按特定顺序包含 3 个并排除所有其他属性。

我已确保我的列表中没有任何重复项。我已经仔细检查过我在“忽略列表”和“包含列表”中没有相同的属性名称。我的这行代码出现异常:XmlSerializer(dataToSerialize.GetType(), allXMLAttribueOverrides);

allXMLAttribueOverrides 从我的方法 GetXMLAttributeOverrides

返回

异常(exception)是:

There was an error reflecting type 'System.Collections.Generic.List`1[SystemName.UserControls.TestMain]'.

内部异常是:

There was an error reflecting property 'TextColumn'.

You need to add XmlChoiceIdentifierAttribute to the 'TextColumn' member.

'TextColumn' 是我测试类中的第一个属性

这是我的测试代码:

TestMain testItem = new TestMain(null, "TextColumnTEST", 5, Convert.ToDecimal(0.333), Convert.ToDecimal(0.777), DateTime.Now, "12:00:00", DateTime.Now, true, "Password", "#FFFFFF", null, null, null);
List<TestMain> dataToSerialize = new List<TestMain>();
dataToSerialize.Add(testItem);

List<string> propertiesToInlcudeInOrder = new List<string>();
propertiesToInlcudeInOrder.Add("CurrencyColumn");
propertiesToInlcudeInOrder.Add("NumberColumn");
propertiesToInlcudeInOrder.Add("TextColumn");

List<string> allColumnNames = new List<string>();
allColumnNames.Add("ID");
allColumnNames.Add("Select");
allColumnNames.Add("TextColumn");
allColumnNames.Add("NumberColumn");
allColumnNames.Add("CurrencyColumn");
allColumnNames.Add("DecimalColumn");
allColumnNames.Add("DateColumn");
allColumnNames.Add("TimeColumn");
allColumnNames.Add("DateAndTimeColumn");
allColumnNames.Add("YesNoColumn");
allColumnNames.Add("PasswordColumn");
allColumnNames.Add("ColorColumn");
allColumnNames.Add("ImageColumn");
allColumnNames.Add("DocumentColumn");
allColumnNames.Add("OtherColumn");

XmlAttributeOverrides allXMLAttribueOverrides = ReportingManipulation.GetXMLAttributeOverrides(dataToSerialize[0].GetType(), propertiesToInlcudeInOrder, allColumnNames);

using (StringWriter mainStringWriter = new StringWriter())
{
XmlSerializer mainXMLSerializer = new XmlSerializer(dataToSerialize.GetType(), allXMLAttribueOverrides);
mainXMLSerializer.Serialize(mainStringWriter, dataToSerialize);
return mainStringWriter.ToString();
}

这是我的测试类:

public class TestMain
{
#region Properties

// Properties

[XmlIgnore]
public int? ID { get; set; }
[XmlIgnore]
public bool Select { get; set; }

public string TextColumn { get; set; }
public int NumberColumn { get; set; }
public decimal CurrencyColumn { get; set; }
public decimal DecimalColumn { get; set; }
public DateTime DateColumn { get; set; }
public string TimeColumn { get; set; }
public DateTime DateAndTimeColumn { get; set; }
public bool YesNoColumn { get; set; }
public string PasswordColumn { get; set; }
public string ColorColumn { get; set; }
public byte[] ImageColumn { get; set; }
public byte[] DocumentColumn { get; set; }
public byte[] OtherColumn { get; set; }

#endregion

#region Constructors

// Constructors
public TestMain()
{
try
{

}
catch (Exception ex)
{
MessageBox.Show("Error at Constructor: 'TestMain'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public TestMain(int? theID, string theTextColumn, int theNumberColumn, decimal theCurrencyColumn, decimal theDecimalColumn, DateTime theDateColumn, string theTimeColumn, DateTime theDateAndTimeColumn, bool theYesNoColumn, string thePasswordColumn, string theColorColumn, byte[] theImageColumn, byte[] theDocumentColumn, byte[] theOtherColumn)
{
try
{
this.ID = theID;

this.TextColumn = theTextColumn;
this.NumberColumn = theNumberColumn;
this.CurrencyColumn = theCurrencyColumn;
this.DecimalColumn = theDecimalColumn;
this.DateColumn = theDateColumn;
this.TimeColumn = theTimeColumn;
this.DateAndTimeColumn = theDateAndTimeColumn;
this.YesNoColumn = theYesNoColumn;
this.PasswordColumn = thePasswordColumn;
this.ColorColumn = theColorColumn;
this.ImageColumn = theImageColumn;
this.DocumentColumn = theDocumentColumn;
this.OtherColumn = theOtherColumn;
}
catch (Exception ex)
{
MessageBox.Show("Error at Constructor: 'TestMain'" + Environment.NewLine + Environment.NewLine + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}

#endregion
}

我哪里错了?

如有任何帮助/建议,我们将不胜感激。

最佳答案

您的基本问题 是您要添加多个覆盖 [XmlElement]每个属性的属性,因为您对所有属性使用单个实例 mainNewXMLAttributes,它累积为所有属性定义的 XmlElementAttribute 对象。

要解决此问题,您需要为 foreach(var propertyNameToIncludeInOrder in propertiesToInlcudeInOrder) 循环中的每个属性分配一个新的 mainNewXMLAttributes,如显示在以下 GetXMLAttributeOverrides() 的更正和简化版本中:

public static partial class ReportingManipulation
{
public static XmlAttributeOverrides GetXMLAttributeOverrides(Type theType, IList<string> propertiesToInlcudeInOrder)
{
var allProperties = theType.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance).Select(p => p.Name);
return GetXMLAttributeOverrides(theType, propertiesToInlcudeInOrder, allProperties);
}

// XML Attribute Overrrides
public static XmlAttributeOverrides GetXMLAttributeOverrides(Type theType, IList<string> propertiesToInlcudeInOrder, IEnumerable<string> allProperties)
{
if (propertiesToInlcudeInOrder == null || propertiesToInlcudeInOrder.Count == 0)
return null;

var theXMLAttributeOverrides = new XmlAttributeOverrides();

// To Add In Order
int counter = 1;
foreach (var propertyNameToIncludeInOrder in propertiesToInlcudeInOrder)
{
// Allocate a fresh instance of XmlAttributes for each property, because we are defining a different
// XmlElementAttribute for each
var mainNewXMLAttributes = new XmlAttributes { XmlIgnore = false };

// Specify the element order XmlElementAttribute and attach to the XmlAttributes
var theXMLElementAttributeToAdd = new XmlElementAttribute { Order = counter };
mainNewXMLAttributes.XmlElements.Add(theXMLElementAttributeToAdd);

// Attach the override XmlElementAttribute to the property propertyNameToIncludeInOrder
theXMLAttributeOverrides.Add(theType, propertyNameToIncludeInOrder, mainNewXMLAttributes);

counter++;
}

// To Ignore
// Using System.Linq.Enumerable.Except()
var propertiesToNotInclude = allProperties.Except(propertiesToInlcudeInOrder);
var ignoreXMLAttributes = new XmlAttributes { XmlIgnore = true };
foreach (var propertyNameToNotInlcude in propertiesToNotInclude)
{
// Attach the override XmlElementAttribute to the property propertyNameToIncludeInOrder
// No need to allocate a fresh instance of ignoreXMLAttributes for each, because the instances would all be identical
theXMLAttributeOverrides.Add(theType, propertyNameToNotInlcude, ignoreXMLAttributes);
}

return theXMLAttributeOverrides;
}
}

为什么您的代码不起作用?在您的初始代码中,您:

XmlAttributes mainNewXMLAttributes = new XmlAttributes();
mainNewXMLAttributes.XmlIgnore = false;

int counter = 1;
foreach (string propertyNameToIncludeInOrder in propertiesToInlcudeInOrder)
{
XmlElementAttribute theXMLElementAttributeToAdd = new XmlElementAttribute(propertyNameToIncludeInOrder);
theXMLElementAttributeToAdd.ElementName = propertyNameToIncludeInOrder;
theXMLElementAttributeToAdd.Order = counter;
mainNewXMLAttributes.XmlElements.Add(theXMLElementAttributeToAdd);

theXMLAttributeOverrides.Add(theType, propertyNameToIncludeInOrder, mainNewXMLAttributes);

counter++;
}

现在,方法XmlAttributeOverrides.Add(Type, String, XmlAttributes)被记录为按如下方式工作:

Adds an XmlAttributes object to the collection of XmlAttributes objects. The type parameter specifies an object to be overridden. The member parameter specifies the name of a member that is overridden.

因此,当最终构造 XmlSerializer 时,mainNewXMLAttributes 的内容将应用于命名参数。当您只为所有参数构造 mainNewXMLAttributes 实例时,它的 XmlElements 数组将包含与 所有 参数相对应的元素名称! IE。您的代码尝试将多个 [XmlElement] 属性应用于每个命名参数,仅在重写名称和顺序上有所不同。这说明了您需要将 XmlChoiceIdentifierAttribute 添加到 'TextColumn' 成员。 异常 - 如果属性值是多态的并且您想要分配不同的元素名称,则只能将多个元素名称附加到属性到不同的值类型。

注意事项

  • 生成带有覆盖的 XmlSerializer 时,您必须静态缓存它并在以后重用它以避免严重的内存泄漏,如 Memory Leak using StreamReader and XmlSerializer 中所述。

  • 我不建议在低级实用方法或对象构造函数中无条件地吞下异常并将它们作为错误消息呈现给用户。

演示工作 fiddle here .

关于c# - : "You need to add XmlChoiceIdentifierAttribute to the member." when using XmlAttributeOverrides?如何解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54476647/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com