将XML响应映射到类?

3
我不知道如何将一些XML表示为C#类。是否有任何建议可以正确地映射此xml?以下是我的尝试:
<authenticationResponse>
  <Accounts>
    <AccountId>1</AccountId>
    <AccountId>5</AccountId>
  </Accounts>
</authenticationResponse>


public class authenticationResponse
{
    [XmlElement("Accounts")]
    [DataMember]
    public List<Account> Accounts { get; set; }
}

public class Account
{
    public long id { get; set; }
}

1
那么,你遇到了什么问题? - John Saunders
我正在使用Microsoft的Webapi从REST端点读取数据。返回的XML中填充了正确的账户ID,但是我的对象中的List为空。 - user486480
请显示完整的 XML。 - John Saunders
4个回答

5
Visual Studio 2012有一个很酷的功能叫做"将XML粘贴为类"(在编辑菜单下的"特殊粘贴"中)。您只需将XML复制到剪贴板中,这个"将XML粘贴为类"功能就会为您生成并粘贴出这个authenticationResponse类:
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class authenticationResponse
{

    private byte[] accountsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayAttribute()]
    [System.Xml.Serialization.XmlArrayItemAttribute("AccountId", IsNullable = false)]
    public byte[] Accounts
    {
        get
        {
            return this.accountsField;
        }
        set
        {
            this.accountsField = value;
        }
    }
}

3
您可以将XML反序列化为以下类:
[XmlRoot("authenticationResponse")] 
public class AuthenticationResponse 
{ 
    [XmlArrayItem("AccountId")] 
    public List<long> Accounts { get; set; } 
}

以下是反序列化的代码:

AuthenticationResponse response = null; 
var serializer = new XmlSerializer(typeof(AuthenticationResponse));

using (StringReader sr = new StringReader(xml)) 
{ 
    response = (AuthenticationResponse)serializer.Deserialize(sr); 
}

谢谢,但这对WebAPI授权不起作用。authResponse = response.Content.ReadAsAsync<authenticationResponse>().Result; - user486480

3
您可以通过LINQ to XML加载这些数据:
XElement x = XElement.Load("YourFile.xml");
List<Account> accounts = x.Element("Accounts")
                            .Elements("AccountId")
                            .Select(e => new Account { id = (long)e })
                            .ToList();

在这种情况下,authenticationResponse类是多余的。
如果你已经将响应保存在内存中(而不是硬盘上的文件),可以使用以下方法:
string response = ...
XElement x = XElement.Load(new StringReader(response));

2
如果您从字符串而不是文件中加载XML,请使用XElement.Parse - Dour High Arch
这行代码无法编译:'Select'引起了问题.... .Select(e => new Account { id = (long)e }) - user486480
错误1:'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>'不包含名为'Select'的定义,也没有接受类型为'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>'的第一个参数的扩展方法'Select'可以找到(是否缺少使用指令或程序集引用?) - user486480
@user486480 要使用此代码,您应该至少使用 .NetFramework 3.5(或更高版本),并将 using System.Linq;using System.Xml.Linq; 添加到您的 using 列表中。 - horgh
@user 以下链接应该是合适的:在C#中使用LINQLINQ to XML - horgh
@user 很高兴能帮到你!以下链接可能会有所帮助:在C#中使用LINQLINQ to XML - horgh

2
我不使用Visual Studio 2012,因此没有“将XML粘贴为类”功能。然而,在这种情况下,如果我需要快速解决方案,我经常使用Visual Studio工具中的xsd.exe程序。它可以从XML Schema定义(.xsd文件)生成一个C#类。
如果您没有所需XML的XSD,您可以从多个XML工具中快速生成一个。我使用oXygen(提供试用版本),加载您的XML示例,然后选择“工具|生成/转换模式”。长期来看,假设您不想依赖第三方工具,我会坚持要求XML数据源也向我提供模式。
样例xsd.exe命令行(从Visual Studio命令提示符中运行):
    xsd.exe FileName.xsd /n:Namespace.Cust.App.UI /c

将会生成一个名为FileName.cs的.cs文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接