C# 修改序列化ASP.NET WebAPI对象中的xml数组元素名称

C# 修改序列化ASP.NET WebAPI对象中的xml数组元素名称,c#,asp.net,xml-serialization,asp.net-web-api,netdatacontractserializer,C#,Asp.net,Xml Serialization,Asp.net Web Api,Netdatacontractserializer,在返回WebAPI控制器中的对象列表时,我一直在努力输出自定义根xml元素 我的控制器方法如下所示: public List<Product> Get() { return repository.GetProducts(); } <ArrayOfProduct> <Product> <Name>Product1</Name> </Product> <Prod

在返回WebAPI控制器中的对象列表时,我一直在努力输出自定义根xml元素

我的控制器方法如下所示:

    public List<Product> Get()
    {
        return repository.GetProducts();
    }
<ArrayOfProduct>
  <Product>
    <Name>Product1</Name>
  </Product>
  <Product>
    <Name>Product2</Name>
  </Product>
</ArrayOfProduct>
公共列表Get()
{
返回repository.GetProducts();
}
它呈现如下xml输出:

    public List<Product> Get()
    {
        return repository.GetProducts();
    }
<ArrayOfProduct>
  <Product>
    <Name>Product1</Name>
  </Product>
  <Product>
    <Name>Product2</Name>
  </Product>
</ArrayOfProduct>

产品1
产品2
我想将
更改为
,但还没有找到这样做的方法

我尝试了
DataContract
DataMember
属性的不同变体,但都没有成功


除了将我的
列表
对象包装到一个新类中并返回该对象之外,有人知道是否有一种方法可以实现我想要的吗?

我猜您使用的是
NetDataContractSerializer

可以在序列化程序的构造函数中指定根元素名称:

NetDataContractSerializer serializer = new NetDataContractSerializer("Products", "Your.Namespace");
请看一下不同的重载:


我遇到了同样的问题,并进行了搜索,但没有找到任何合适的解决方案,因此最终决定将字符串“ArrayOfProduct”替换为“Products”,并且它工作正常


我知道这样做不好,但速度很快。

您应该能够按照概述使用Xml序列化工具

我已经有一段时间没有和他们一起工作了,但是他们学习起来又快又容易。

课程计划
class Program
{
    static void Main(string[] args)
    {
        HttpConfiguration config = new HttpConfiguration();

        DataContractSerializer productsSerializer = new DataContractSerializer(typeof(List<Product>), "Products", String.Empty);
        config.Formatters.XmlFormatter.SetSerializer(typeof(List<Product>), productsSerializer);

        config.Formatters.XmlFormatter.Indent = true;

        config.Formatters.XmlFormatter.WriteToStreamAsync(
            typeof(List<Product>),
            new List<Product> { new Product { Name = "Product1" }, new Product { Name = "Product2" } },
            Console.OpenStandardOutput(),
            null,
            null).Wait();

        Console.WriteLine();
    }
}

[DataContract(Namespace = "")]
public class Product
{
    [DataMember]
    public string Name { get; set; }
}
{ 静态void Main(字符串[]参数) { HttpConfiguration config=新的HttpConfiguration(); DataContractSerializer productsSerializer=新的DataContractSerializer(typeof(List),“Products”,String.Empty); config.Formatters.XmlFormatter.SetSerializer(typeof(List),productsSerializer); config.Formatters.XmlFormatter.Indent=true; config.Formatters.XmlFormatter.WriteToStreamAsync( 类型(列表), 新列表{new Product{Name=“Product1”},新产品{Name=“Product2”}, Console.OpenStandardOutput(), 无效的 null)。等待(); Console.WriteLine(); } } [DataContract(名称空间=”)] 公共类产品 { [数据成员] 公共字符串名称{get;set;} }
我已经做了很多次,自定义xml序列化输出。在我的类定义中使用属性:

[XmlArray("Products")]
public List<Product> Products
{
    get { return repository.GetProducts(); }
}
[XmlArray(“产品”)]
公开上市产品
{
获取{return repository.GetProducts();}
}

这将为您提供所需的输出…

我知道您不喜欢包装器的想法,但有一种解决方案在某种程度上使用了包装器,但也使用了非常容易使用的xml属性。我拒绝使用以下方法是因为使用了旧的序列化程序

public class Product
{
    [XmlAttribute( "id" )]
    public int Id
    {
        get;
        set;
    }
    [XmlAttribute( "name" )]
    public string Name
    {
        get;
        set;
    }
    [XmlAttribute( "quantity" )]
    public int Quantity
    {
        get;
        set;
    }
}
[XmlRoot( "Products" )]
public class Products
{
    [XmlAttribute( "nid" )]
    public int Id
    {
        get;
        set;
    }
    [XmlElement(ElementName = "Product")]
    public List<Product> AllProducts { get; set; }
}
公共类产品
{
[XmlAttribute(“id”)]
公共整数Id
{
得到;
设置
}
[XmlAttribute(“名称”)]
公共字符串名
{
得到;
设置
}
[XmlAttribute(“数量”)]
公共整数
{
得到;
设置
}
}
[XmlRoot(“产品”)]
公共类产品
{
[XmlAttribute(“nid”)]
公共整数Id
{
得到;
设置
}
[XmlElement(ElementName=“产品”)]
公共列表所有产品{get;set;}
}
现在,您的控制器可以返回以下产品:

    public Products Get()
    {
        return new Products
        {
            AllProducts = new List<Product>
            {
                new Product {Id = 1, Name = "Product1", Quantity = 20},
                new Product {Id = 2, Name = "Product2", Quantity = 37},
                new Product {Id = 3, Name = "Product3", Quantity = 6},
                new Product {Id = 4, Name = "Product4", Quantity = 2},
                new Product {Id = 5, Name = "Product5", Quantity = 50},
            }
        };
    }
公共产品获取()
{
退回新产品
{
AllProducts=新列表
{
新产品{Id=1,Name=“Product1”,数量=20},
新产品{Id=2,Name=“Product2”,数量=37},
新产品{Id=3,Name=“Product3”,数量=6},
新产品{Id=4,Name=“Product4”,数量=2},
新产品{Id=5,Name=“Product5”,数量=50},
}
};
}
现在,您可以在启动时指定序列化程序,如下所示:

    var productssXmlFormatter = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
    productssXmlFormatter.SetSerializer<Products>( new XmlSerializer( typeof( Products ) ) );
var productsSsXmlFormatter=GlobalConfiguration.Configuration.Formatters.XmlFormatter;
ProductsSsXmlFormatter.SetSerializer(新的XmlSerializer(产品类型));
我知道这不是最理想的方式,因为它必须指定序列化程序,并失去EF和Linq的灵活性和便利性。或者至少必须介入,而不仅仅是返回IEnumerable

我必须赞扬以下网站,因为我第一次从以下网站了解到这种方式:

这将产生以下xml:

<Products nid="0">
    <Product id="1" name="Product1" quantity="20"/>
    <Product id="2" name="Product2" quantity="37"/>
    <Product id="3" name="Product3" quantity="6"/>
    <Product id="4" name="Product4" quantity="2"/>
    <Product id="5" name="Product5" quantity="50"/>
 </Products>


请不要忘记查看列出的网站。

请查看此网站。有一些关于如何以xml格式配置类的输出的信息

在我看来,这与wep api无关,而是与类的配置有关。

如难以捉摸所说

[XmlArray("Products")]
public List<Product> Get()
{
    return repository.GetProducts();
}

注意:要重命名
产品
项目标记,可以使用
[XmlArrayItem(“产品”)]
属性来完成此操作。如果您想要一个简单的列表(不要将它们包装在“产品”中),您可以使用
[xmlement(“产品”)]
,这样就可以列出它们,而无需对它们进行分组。

谢谢,但我不会手动序列化我的对象。我的操作方法将我的对象返回到
System.Web.Http.ApiController
,因此我不知道如何从那里控制输出?XmlArrayAttribute在方法上无效。@PeterHedberg您是对的。编辑以反映属性语法而不是方法。这里是类似的线程-。提供的答案可以通过ActionFilters轻松改进,使其更通用、更具声明性。这段代码给出了一个错误“xmlarray在此声明类型上无效”。你能建议一条出路吗?