【问题标题】:ArrayOf when using List<T> with a WCF Rest Service将 List<T> 与 WCF 休息服务一起使用时的 ArrayOf
【发布时间】:2010-06-21 20:07:07
【问题描述】:

我正在尝试使用 .NET 4.0 和 WCF 创建 REST Web 服务。我的 REST 服务返回一个列表,然后将其序列化为 XML。我遇到的问题是返回的 XML 以我不喜欢的 ArrayOf 开头。

换句话说,现在 XML 看起来像这样:

<ArrayOfAchievement>
    <Achievement>
        ...
    </Achievement>
</ArrayOfAchievement>

我希望 XML 看起来像这样:

<Achievements>
    <Achievement>
        ...
    </Achievement>
</Achievements>

如果我创建一个新类并将其命名为AchievementsList,它具有List的属性,如下所示:

public class AchievementsList
{
    public List<Achievement> Achievements { get; set; }
}

然后让我的服务返回上面的类而不是 List,XML 最终看起来像这样:

<AchievementsList>
    <Achievements>
        <Achievement>
            ...
        </Achievement>
    </Achievements>
</AchievementsList>

这是错误的(因为它添加了另一个不属于那里的级别)。

另一个问题是我还需要为对象应用命名空间,如下所示:

[XmlRoot(Namespace="NameSpaceURL")]
public class AchievementsList
{
    public List<Achievement> Achievements { get; set; }
}

如果我只返回一个列表,这是我做不到的。

那么我该怎么解决这两个问题呢?

巴拉

【问题讨论】:

    标签: .net list wcf rest


    【解决方案1】:
    1. 使用AchievementList 类,你走在了正确的轨道上,但你需要做的是用XmlElement 属性装饰Achievements 列表属性,并提供各个元素的名称。

    2. 命名空间在 AchievementList 类上,就像你拥有它一样。

    示例代码:

    [Serializable]
    public class Achievement {
        public string Name { get; set; }
    }
    
    [Serializable]
    [XmlRoot(ElementName="Achievements", Namespace="http://www.mynamespace.com")]
    public class AchievementList
    {      
        [XmlElement("Achievement")]
        public List<Achievement> Achievements { get; set; }
    
        public AchievementList()
        {
            Achievements = new List<Achievement>();
        }
    
        public void Add(Achievement a)
        {
            Achievements.Add(a);
        }
    }
    

    您的输出将类似于:

    <?xml version="1.0" encoding="utf-16"?>
    <Achievements xmlns="http://www.mynamespace.com">
      <Achievement>
        <Name>Woke Up</Name>
      </Achievement>
      <Achievement>
        <Name>Went to work</Name>
      </Achievement>
      <Achievement>
        <Name>Slacked off</Name>
      </Achievement>
    </Achievements>}
    

    【讨论】:

    • 当我添加 ElementName 属性时,没有任何反应。这是我的代码:screencast.com/t/MGJkY2MxY ...如果我更改它以便 DataContract 和 DataMember 更改元素名称,它会做一些奇怪的事情。这是这种情况下的代码:screencast.com/t/MGZkY2M0O ... 结果:screencast.com/t/OWYxYmRlZmQt
    • [XmlElement("Achievement")] 仅将Achievements 的子元素设置为“Achievement”——它仍然为您留下3 个级别的元素。
    • 我在建议之前测试了我发布的代码,输出是我的测试控制台应用程序吐出的内容的复制和粘贴。随意将其插入您自己的测试应用中,如果您得到不同的结果,请告诉我。
    • 这也没有达到我要求的结果。
    【解决方案2】:

    我有一个类似的设置,如下所示:从List&lt;Achievement&gt; 派生AchievementsList,用XmlTypeAttributeXmlRootAttribute 装饰它,并用XmlTypeAttribute 装饰Achievement

    [XmlType(TypeName = "Achievements", Namespace="http://www.mynamespace.com")]
    [XmlRoot(ElementName = "Achievements", Namespace="http://www.mynamespace.com")]
    public class AchievementsList : List<Achievement>
    {
    }
    
    [XmlType(TypeName = "Achievement", Namespace="http://www.mynamespace.com")]
    public class Achievement
    {
        ...
    }
    

    我还用XmlSerializerFormat 属性修饰了我的服务实现,这样我就可以避免通常的DataContract 序列化。

    【讨论】:

      【解决方案3】:

      我向related question 询问了如何反序列化由返回List&lt;SomeType&gt; 的WCF Web 服务方法生成的XML。

      XML 有一个名为&lt;ArrayOfSomeType&gt; 的根,为了将其反序列化回List&lt;SomeType&gt;,必须使用DataContractSerializer 而不是XmlSerializer,因为它们不兼容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-28
        • 2016-02-23
        • 1970-01-01
        • 2013-03-25
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 2011-08-10
        相关资源
        最近更新 更多