You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XmlSerializer序列化含PSCredential的C#对象至XML时字段为空的问题

解决PSCredential的XML序列化问题

你遇到的问题本质是XmlSerializer默认不支持序列化PSCredential类型:

  • PSCredential内部的Password是SecureString,这是一种加密的、不可直接读取的类型,XmlSerializer无法自动处理它的序列化。
  • 同时PSCredential本身没有标记[Serializable]属性,也没有公开可被序列化的字段,所以默认序列化只会生成空标签。

要实现PSCredential的XML序列化,不能直接依赖XmlSerializer的默认行为,必须自定义序列化逻辑,以下是具体实现方案:

自定义序列化逻辑(实现IXmlSerializable接口)

通过让你的CustomObject实现IXmlSerializable接口,手动控制PSCredential的序列化和反序列化流程。核心思路是利用PowerShell的ConvertFrom-SecureString和ConvertTo-SecureString命令,把SecureString转换成可序列化的加密字符串,再写入XML;反序列化时再把加密字符串转回SecureString。

示例代码:

using System.Xml;
using System.Xml.Serialization;
using System.Management.Automation;

public class CustomObject : IXmlSerializable
{
    public PSCredential DatabaseCredential { get; set; }
    public PSCredential LaneCredential { get; set; }

    public XmlSchema GetSchema() => null;

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement();
        
        // 读取DatabaseCredential
        reader.ReadStartElement("DatabaseCredential");
        var dbUsername = reader.ReadElementContentAsString("Username", "");
        var dbEncryptedPwd = reader.ReadElementContentAsString("SecurePassword", "");
        DatabaseCredential = new PSCredential(dbUsername, ConvertToSecureString(dbEncryptedPwd));
        reader.ReadEndElement();

        // 读取LaneCredential
        reader.ReadStartElement("LaneCredential");
        var laneUsername = reader.ReadElementContentAsString("Username", "");
        var laneEncryptedPwd = reader.ReadElementContentAsString("SecurePassword", "");
        LaneCredential = new PSCredential(laneUsername, ConvertToSecureString(laneEncryptedPwd));
        reader.ReadEndElement();

        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        // 序列化DatabaseCredential
        writer.WriteStartElement("DatabaseCredential");
        writer.WriteElementString("Username", DatabaseCredential.UserName);
        writer.WriteElementString("SecurePassword", ConvertFromSecureString(DatabaseCredential.Password));
        writer.WriteEndElement();

        // 序列化LaneCredential
        writer.WriteStartElement("LaneCredential");
        writer.WriteElementString("Username", LaneCredential.UserName);
        writer.WriteElementString("SecurePassword", ConvertFromSecureString(LaneCredential.Password));
        writer.WriteEndElement();
    }

    // 封装PowerShell的SecureString转加密字符串逻辑
    private string ConvertFromSecureString(SecureString secureStr)
    {
        using var ps = PowerShell.Create();
        ps.AddCommand("ConvertFrom-SecureString").AddParameter("SecureString", secureStr);
        return ps.Invoke<string>().FirstOrDefault();
    }

    // 封装加密字符串转SecureString逻辑
    private SecureString ConvertToSecureString(string encryptedStr)
    {
        using var ps = PowerShell.Create();
        ps.AddCommand("ConvertTo-SecureString").AddParameter("String", encryptedStr);
        return ps.Invoke<SecureString>().FirstOrDefault();
    }
}

注意事项

  1. 安全性:ConvertFrom-SecureString默认使用当前用户的加密密钥生成字符串,只有同一用户在同一机器上才能解密,避免了明文存储密码的风险。如果需要跨用户/机器使用,可添加-Key参数指定自定义密钥,但密钥必须妥善保管。
  2. 替代方案:如果你的场景允许,也可以直接使用PowerShell内置的Export-Clixml和Import-Clixml命令(在C#中通过PowerShell类调用),它们原生支持PSCredential的序列化,无需手动实现逻辑。

内容的提问来源于stack exchange,提问作者Qrm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:50:14