【问题标题】:System.InvalidOperationException : <LicenseBase xmlns=''> was not expectedSystem.InvalidOperationException:<LicenseBase xmlns=''> 不是预期的
【发布时间】:2021-08-23 15:10:48
【问题描述】:

我尝试序列化和反序列化类许可证。

序列化运行良好,但是当我尝试反序列化文件时 我收到上面的错误消息。

这是基类:

[Serializable]
public abstract class LicenseBase
{
    /// <summary>
    /// Initializes a new instance of the <see cref="LicenseBase"/> class.
    /// </summary>
    protected LicenseBase()
    {
        ApplicationName = string.Empty;
        UniqueId = string.Empty;
    }
    /// <summary>
    /// Application name this license is used for 
    /// </summary>
    [Browsable(false)]
    public string ApplicationName { get; set; }

    /// <summary>
    /// Unique hardware id this license will work on
    /// </summary>
    [Browsable(false)]
    public string UniqueId { get; set; }
}

这是派生的:

public class License : LicenseBase
{
    [Browsable(false)]
    public bool Test { get; set; }
}

这是序列化类的方法:

public void WriteLicense<T>(T license) where T : LicenseBase
    {
        if (license is null)
        {
            throw new ArgumentNullException(nameof(license));
        }
        //Serialize license object into XML                    
        XmlDocument licenseObject = new XmlDocument();
        using (StringWriter writer = new StringWriter())
        {
            XmlSerializer serializer = new XmlSerializer(typeof(LicenseBase), new[]
            {
                license.GetType(), typeof(License)
            });
            serializer.Serialize(writer, license);
            licenseObject.LoadXml(writer.ToString());
        }

        //Sign the XML
        SignXml(licenseObject);

        //Convert the signed XML into BASE64 string            
        string writeToFile = Convert.ToBase64String(Encoding.UTF8.GetBytes(licenseObject.OuterXml));

        File.WriteAllText(LICENSE_FILENAME, writeToFile);
    }

这是读取类的代码:

    public T ReadLicense<T>() where T : LicenseBase
    {
        T license;

        if (!File.Exists(LICENSE_FILENAME))
        {
            alarmManager.ReportAlarm(licenseFileMissingAlarm, true, true);
            return null;
        }
        string licenseFileData = File.ReadAllText(LICENSE_FILENAME);

        XmlDocument xmlDoc = new XmlDocument { PreserveWhitespace = true };
        xmlDoc.LoadXml(Encoding.UTF8.GetString(Convert.FromBase64String(licenseFileData)));
        // Verify the signature of the signed XML.            
        if (VerifyXml(xmlDoc, PrivateKey))
        {
            XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signature");
            if (xmlDoc.DocumentElement != null)
            {
                _ = xmlDoc.DocumentElement.RemoveChild(nodeList[0]);
            }

            string licenseContent = xmlDoc.OuterXml;

            //Deserialize license
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            using (StringReader reader = new StringReader(licenseContent))
            {
                license = (T)serializer.Deserialize(reader);
            }
        }
        else
        {
            license = null;
        }

        return license;
    }

licenseContent的内容是

<?xml version="1.0" encoding="UTF-8"?>
<LicenseBase xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="License">
   <ApplicationName>Test</ApplicationName>
   <UniqueId>c4aed5a8-8d22-47b0-bda4-700ac906bfd5</UniqueId>
   <Test>true</Test>
</LicenseBase>

【问题讨论】:

  • 我通过验证器 here 运行了您的 XML,并收到消息 “无法将 'License' 解析为元素 'LicenseBase' 的类型定义。”
  • 我们可以查看您的许可证类别吗?
  • 也许您需要为XmlSerializer 使用不同的构造函数,在其中定义哪个节点是根节点(根据此answer)。请注意,在这里您将使用字符串“LicenseBase”而不是链接答案中的字符串。
  • 元素名称是LicenseBase,并且有一个属性xsi:type="License",这意味着XML是通过使用XML序列化程序new XmlSerializer(typeof(LicenseBase))序列化License类型的对象创建的。您需要在反序列化上做同样的事情,将[XmlInclude(typeof(License))] 应用于LicenseBase。为什么请参阅c# xml deserialization to object with colon and hyphen in xsi:type valueSerialize/Deserialize derived class as base class
  • 事实上这可能是这两个的副本,同意吗?如果没有,您能否请edit 分享您的问题minimal reproducible example,特别是您尝试反序列化的与通用参数T 相对应的实际类型?

标签: c# xml


【解决方案1】:

我解决了这个是失败的问题;

   XmlSerializer serializer = new XmlSerializer(typeof(LicenseBase), new[]
        {
            license.GetType(), typeof(License)
        });

这是解决方案:

  XmlSerializer serializer = new XmlSerializer(license.GetType(), new[]
            {
                license.GetType()
            });

更改后一切正常。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2021-02-08
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多