14

在我的WebAPI控制器中返回對象列表時,我一直在努力輸出自定義根元素xml元素。在序列化的ASP.NET WebAPI對象中修改xml數組元素名稱

我控制器的方法看起來是這樣的:

public List<Product> Get() 
    { 
     return repository.GetProducts(); 
    } 

這使得一個XML輸出是這樣的:

<ArrayOfProduct> 
    <Product> 
    <Name>Product1</Name> 
    </Product> 
    <Product> 
    <Name>Product2</Name> 
    </Product> 
</ArrayOfProduct> 

我想改變<ArrayOfProduct><Products>但還沒有找到一種方式這樣做。

我已經嘗試了DataContractDataMember屬性的不同變體無濟於事。

有沒有人知道是否有辦法做我想做的事情,將我的List<Product>對象包裝到一個新類中,然後返回它?

+0

這裏是類似的線程 - http://stackoverflow.com/a/11794647/2152334。提供的答案可以通過ActionFilters輕鬆改進,使其更具通用性和聲明性。 – Yura 2015-03-31 15:32:52

回答

0

我猜你正在使用NetDataContractSerializer
您可以在串行器的構造函數中指定的根元素名稱:

NetDataContractSerializer serializer = new NetDataContractSerializer("Products", "Your.Namespace"); 

看看該型動物重載:

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.netdatacontractserializer.aspx

+0

謝謝,但我不是手動序列化我的對象。我的動作方法返回我的對象​​到'System.Web.Http.ApiController',所以我不明白我可以如何控制從那裏的輸出? – heidgert 2012-08-03 09:41:10

0

我面臨着同樣的問題和搜索,但找不到任何適當的解決方案,所以最終決定用「產品」替換字符串「ArrayOfProduct」,它是w分工平穩。

我知道這是不好的方法來做到這一點,但它很快。

0

您應該能夠使用XML序列化attirbues所概述here

它已經有一段時間,因爲我已經與他們合作,但他們快速,簡單易學。

1
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; } 
} 
0

我已經做了很多次,自定義xml序列化輸出。在我的類定義使用屬性:

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

這應該得到你正在尋找我知道你不喜歡包裝的想法,但沒有多少有些使用的包裝解決方案的輸出...

+4

XmlArrayAttribute在方法上無效。 – 2013-03-02 10:43:50

+0

@PeterHedberg你是對的。編輯以反映屬性語法而非方法。 – jogi 2018-02-05 18:24:11

1

還使用了非常容易處理的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; } 
} 

現在你的控制器可以只返回產品,如:

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}, 
      } 
     }; 
    } 

現在你可以指定在啓動時的串行像這樣:

var productssXmlFormatter = GlobalConfiguration.Configuration.Formatters.XmlFormatter; 
    productssXmlFormatter.SetSerializer<Products>(new XmlSerializer(typeof(Products))); 

我知道這是不是最不得不指定序列化器並失去EF和Linq的靈活性和便利性。或者至少不得不介入而不是僅僅返回IEnumerable <>。

我必須給予信貸以下網站作爲我第一次聽說這種方式從網站:http://justthisguy.co.uk/outputting-custom-xml-net-web-api/

這將導致以下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> 

請不要忘記看看列出的網站。

1

難以捉摸說....

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

如果您有問題,因爲它是一種方法,然後嘗試重新定義爲一個屬性,因爲它不帶任何參數,並可能更有意義。

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

這將在名爲'Products'的元素元素中列出所有Product項目。

<Products> 
    <Product> 
    <Name>Product1</Name> 
    </Product> 
    <Product> 
    <Name>Product2</Name> 
    </Product> 
</Products> 

P.S.要重命名Product商品代碼,您可以使用[XmlArrayItem("Product")]屬性來執行此操作。如果你想有一個扁平的列表(不要將它們包裝在'產品'中),你可以使用[XmlElement("Product")],這將列出它們而不分組。

+1

嗨。此代碼給我一個錯誤「xmlarray在這種聲明類型上無效」。你能提出一條出路嗎? – 2016-10-16 16:26:24

相關問題