14

Ich habe Schwierigkeiten mit der Ausgabe eines benutzerdefinierten Root-XML-Elements beim Zurückgeben einer Liste von Objekten in meinem WebAPI-Controller.Ändern Sie den Namen des XML-Array-Elements in serialisierten ASP.NET-WebAPI-Objekt

Mein Controller-Methode sieht wie folgt aus:

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

, die eine XML-Ausgabe so macht:

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

Ich möchte <ArrayOfProduct> zu <Products> ändern haben, aber nicht einen Weg gefunden so tun.

Ich habe verschiedene Varianten der DataContract und DataMember Attribute vergeblich versucht.

Weiß jemand, ob es einen Weg gibt, zu tun, was ich will, kurz, mein List<Product>-Objekt in eine neue Klasse zu wickeln und das stattdessen zurückzugeben?

+0

Hier ist ein ähnlicher Thread - http://Stackoverflow.com/a/11794647/2152334. Die angegebene Antwort kann über ActionFilters leicht verbessert werden, um generischer und deklarativer zu sein. – Yura

Antwort

0

Ich glaube, Sie verwenden NetDataContractSerializer
Sie das Stammelement Name im Konstruktor des Serializer angeben:

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

Werfen Sie einen Blick auf den differents Überlastungen:

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

+0

Danke, aber ich bin nicht manuell serialisieren mein Objekt. Meine Aktionsmethode gibt mein Objekt an den 'System.Web.Http.ApiController' zurück, so dass ich nicht sehe, wie ich die Ausgabe von dort aus steuern kann? – heidgert

0

I war mit dem gleichen Problem konfrontiert und suchte, konnte aber keine richtige Lösung finden, so entschied sich schließlich, die Zeichenfolge "ArrayOfProduct" durch "Produkte" zu ersetzen und es ist w orking glatt.

Ich weiß, es ist ein schlechter Weg, dies zu tun, aber es ist schnell.

0

Sie sollten in der Lage sein, die XML-Serialisierung attirbues zu verwenden, wie here skizzierte

Es ist schon eine Weile her, seit ich mit ihnen gearbeitet haben, aber sie waren schnell und einfach zu erlernen.

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

Ich habe dies viele Male getan, XML-Serialisierung Ausgabe angepasst. Mit Attributen in meiner Klassendefinitionen:

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

dies sollten Sie die Ausgabe erhalten Sie suchen ...

+4

XmlArrayAttribute ist für Methoden nicht gültig. –

+0

@PeterHedberg Sie sind richtig. bearbeitet, um Eigenschaftssyntax nicht Methode widerzuspiegeln. – jogi

1

Ich weiß, dass Sie nicht gern die Wrapper-Idee, aber es gibt eine Lösung, die etwas ein Wrapper verwendet verwendet aber auch die XML-Attribute, mit denen sehr einfach zu arbeiten ist. Meine Weigerung, den folgenden Ansatz zu verwenden, ist die Verwendung des alten Serialisierers.

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

Jetzt Ihr Controller kann nur Produkte zurückgeben wie:

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

jetzt können Sie den Serializer in Start-up angeben wie folgt:

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

Ich weiß, es ist nicht die Der ideale Weg, um den Serializer zu spezifizieren und die Flexibilität und den Komfort von EF und Linq zu verlieren. Oder zumindest eingreifen müssen statt nur IEnumerable zurückgeben <>. Dies führt in der folgenden XML-http://justthisguy.co.uk/outputting-custom-xml-net-web-api/

:

Ich habe Kredit auf der folgenden Website zu geben, wie ich das erste dieser Art und Weise von der Website auf gelernt

<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> 

Bitte vergessen Sie nicht, um die gelistete Seite zu sehen.

1

Wie schwer sagte ....

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

Wenn Sie Probleme haben, weil es ein Verfahren ist, dann versuchen Sie es als eine Eigenschaft neu zu definieren, da es keine Parameter, und macht wahrscheinlich mehr Sinn.

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

Das listet alle Product Elemente innerhalb eines Elements Element mit dem Namen 'Produkte'.

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

P.S. Um die Element-Tags Product umzubenennen, können Sie dazu das Attribut [XmlArrayItem("Product")] verwenden. Wenn Sie eine flache Liste haben möchten (nicht in "Produkte" umbrechen), können Sie die [XmlElement("Product")] verwenden und diese auflisten, ohne sie zu gruppieren.

+1

Hallo. Dieser Code gibt mir einen Fehler "der Xmlarray ist nicht gültig für diesen Deklarationstyp". Kannst du einen Ausweg vorschlagen? –

Verwandte Themen