【问题标题】:Unable to Serialize array Object in C#无法在 C# 中序列化数组对象
【发布时间】:2020-04-03 13:53:53
【问题描述】:

我有以下课程:

public partial class ct_ServiceProductInfoWireless {

    private object[] itemsField;
    private bool directFulfillmentField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("NewWirelessLines", typeof(ct_WirelessLines))]
    [System.Xml.Serialization.XmlElementAttribute("WirelessLine", typeof(ct_ServiceProductInfoWirelessWirelessLine))]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

ct_WirelessLines 类

public partial class ct_WirelessLines {

    private ct_NewWirelessLine[] wirelessLineField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("WirelessLine")]
    public ct_NewWirelessLine[] WirelessLine {
        get {
            return this.wirelessLineField;
        }
        set {
            this.wirelessLineField = value;
        }
    }
}

问题是当我序列化我的 ct_ServiceProductInfoWireless 对象时,我得到以下异常:

类型 ct_WirelessLines[] 不能在此上下文中使用。

这是序列化代码:

var stringWriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(objectToSerialize.GetType());
serializer.Serialize(stringWriter, objectToSerialize); //Getting exception here
return stringWriter.ToString();

怎么了?

ct_NewWirelessLine 类

public partial class ct_NewWirelessLine {

    private ct_NewRatePlan ratePlanField;

    private ct_DataPlan dataPlanField;

    private ct_OrderDevice deviceField;

    private ct_PhoneNumber telephoneNumberField;

    private string lineNumberField;

    private bool isPrimaryLineField;
}

ct_ServiceProductInfoWirelessWirelessLine 类

public partial class ct_ServiceProductInfoWirelessWirelessLine {

    private ct_Device deviceField;

    private ct_RatePlan ratePlanField;

    private ct_InstallmentPlan installmentPlanField;

    private string paymentArrangementField;

    private ct_OptionalFeature[] optionalPackagesField;

    private ct_WirelessFeature[] optionalFeaturesField;

    private string lineNumberField;

    private string primarySQNumberField;

    private string secondarySQNumberField;

    private st_CustomerType customerTypeField;

    private bool customerTypeFieldSpecified;

    private string ppuZipField;

    private string wtnField;

    private bool directFulfillmentField;

    private bool directFulfillmentFieldSpecified;
}

【问题讨论】:

  • 请发布ct_ServiceProductInfoWirelessWirelessLinect_NewWirelessLine 类,因为当我创建这些自定义类时它运行良好,因此问题可能出在这些类定义中。
  • 我无法在您的代码中确定问题的确切位置。然而,发现下面的文章有一个类似的问题和一些答案。希望它能帮助您找到解决方法的线索。 stackoverflow.com/questions/3897818/…
  • 你有大量的类,从 cmets 开始,找出许多属性,直到找到有问题的类定义。
  • 私有属性不会被序列化。
  • 我能够通过将ct_ServiceProductInfoWireless.Items 指定为ct_WirelessLines 的数组而不是一维数组来获得错误消息System.InvalidOperationException: The type ct_WirelessLines[] may not be used in this context.Items = new [] { new [] { new ct_WirelessLines() } }。演示小提琴:dotnetfiddle.net/PaXdUR。代码编译是因为Items 只是一个对象数组,但不会序列化,因为XmlSerializer 只需要数组中两个声明类型的对象,而不是一些嵌套数组。你能做到吗?

标签: c# arrays xml serialization xmlserializer


【解决方案1】:

我能够重现错误消息

System.InvalidOperationException: The type ct_WirelessLines[] may not be used in this context.

通过将ct_ServiceProductInfoWireless.Items 指定为一个ct_WirelessLines 的数组,而不是一维数组:

Items = new [] { new [] { new ct_WirelessLines() } }`

此代码可以编译,因为Items 只是一个对象数组,但不会序列化,因为XmlSerializer 只希望在数组中声明XmlElementAttribute.Type 属性中声明的两种类型的对象,而不是一些嵌套数组.演示小提琴#1 here

解决方案是不这样做并使用平面一维数组:

Items = new [] { new ct_WirelessLines() },

演示小提琴 #2 here.

如果您有两个集合,一个是ct_WirelessLines,一个是ct_ServiceProductInfoWirelessWirelessLine,您可以通过将集合内容向上转换为object,然后使用Concat() 和@,将它们组合成最终的Items 数组987654325@:

var wirelessLines = GetWirelessLines(); // Some IEnumerable<ct_WirelessLines>
var productInfo = GetProductInfoWirelessWirelessLines(); // Some IEnumerable<ct_ServiceProductInfoWirelessWirelessLine>

var objectToSerialize = new ct_ServiceProductInfoWireless
{
    Items = wirelessLines.Cast<object>().Concat(productInfo).ToArray(),
};

演示小提琴#3 here.

顺便说一句,这段代码看起来好像是由xsd.exe 自动生成的。该工具通常不会为选择元素序列自动生成类层次结构。但是,如果您可以手动修改生成的代码,您可以为您的Items 引入一个抽象基类,这将防止您在编译时遇到的那种错误:

public partial class ct_ServiceProductInfoWireless 
{
    private WirelessItemBase[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("NewWirelessLines", typeof(ct_WirelessLines))]
    [System.Xml.Serialization.XmlElementAttribute("WirelessLine", typeof(ct_ServiceProductInfoWirelessWirelessLine))]
    public WirelessItemBase[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

public abstract class WirelessItemBase
{
}

public partial class ct_WirelessLines : WirelessItemBase
{
}

public partial class ct_ServiceProductInfoWirelessWirelessLine : WirelessItemBase
{
}

现在甚至无法编译:

Items = new [] { new [] { new ct_WirelessLines() } }, //Compilation error (line 72, col 13): Cannot implicitly convert type 'ct_WirelessLines[][]' to 'WirelessItemBase[]'

演示小提琴#4 here.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多