2009-12-23 20 views
11

Korzystanie DataContractSerializer serializować mojego obiektu pojawia się wynik podobny doCzy istnieje sposób, aby przekształcić XML danych wyjściowych programu DataContractSerializer?

<?xml version="1.0" encoding="utf-8" ?> 
<AgentNotification xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/The.name.space.Notifications"> 
    <_x003C_Created_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
    <_x003C_Id_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" />   
<_x003C_Email_x003E_k__BackingField>[email protected]</_x003C_Email_x003E_k__BackingField> 
    <_x003C_Name_x003E_k__BackingField>Random Person</_x003C_Name_x003E_k__BackingField> 
<_x003C_Policies_x003E_k__BackingField> 
<PolicyNotification> 
    <_x003C_Created_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
    <_x003C_Id_x003E_k__BackingField i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/The.name.space" /> 
    <_x003C_ConfirmationNumber_x003E_k__BackingField>Some number</_x003C_ConfirmationNumber_x003E_k__BackingField> 
    </PolicyNotification> 
<PolicyNotification> 
    </_x003C_Policies_x003E_k__BackingField> 
    </AgentNotification> 

Czy jest jakiś sposób na to tagów wyjściowych, które są po prostu

<Id> 
<Name> 

etc, bez konieczności pokrycia moje zajęcia z atrybutami?

Jeśli nie ma sposobu, aby to wyjście było gwarantowane za każdym razem prawidłowe? Tak więc, jeśli użyję tego do renderowania wykresów obiektów, to XML będzie mieszał się z dokumentem X * do generowania pliku, że nigdy nie napotkasz problemu, w którym moje węzły zmieniają nazwy, a dokument jest pusty.

+3

Nie. Przestań się martwić, jak wygląda Twój xml. Doprowadza tylko do złamanego serca. – Will

+0

Powinieneś zrobić odpowiedź. –

Odpowiedz

8

Dzieje się tak, ponieważ musisz zaznaczyć swoje typy (na przykład AgentNotification) za pomocą [Serializable]. Gdy DataContractSerializer napotyka typ oznaczony [Serializable], ale nie ma wyraźnego [DataContract], generuje on default contract dla typu, który pasuje do tego, jak BinaryFormatter serializuje klasę, co ma na celu serializację all member variables of a class — even variables marked as private - według nazwy.W przypadku auto-implemented properties oznacza to, że secret backing fields jest serializowane według nazwy; ich imiona są szczególnymi nazwami elementów, które widzisz.

Najprostszym sposobem rozwiązania tego problemu jest usunięcie atrybutu [Serializable] ze swoich klas. Prawie na pewno nie potrzebujesz tego, chyba że faktycznie używasz BinaryFormatter lub SoapFormatter. Po wykonaniu tej czynności DataContractSerializer będzie teraz serializować twoje publiczne właściwości i pola według nazwy, a nie publiczne i prywatne pola według nazwy.

+0

To prawdopodobnie byłby to, co chciałem 6 lat temu. Ale w pewnym momencie przestałem używać XSLT i zacząłem używać Postal + RazorViewEngine do generowania treści wiadomości e-mail. –

1

Numeracja DataContractSerializer będzie serializować wszystkie właściwości publiczne (jeśli nic nie określono - możliwe od .NET 3.5 SP1) lub (preferowane przeze mnie podejście) wszystko, co oznakujesz za pomocą atrybutu [DataMember].

Tak najlepiej można zrobić, to zaznaczyć swoją klasę z atrybutem [DataContract], a wszyscy jej członkowie (właściwości, pola, etc.), które naprawdę chcą w umowie danych z atrybutem [DataMember].

DataContractSerializer naprawdę nie pozwala znacznie większą kontrolę niż to - można określić dość wyraźnie (przy użyciu tego wyraźnego „opt-in” podejście) co dostaje odcinkach, ale mają niewielką lub żadną kontrolę nad jak to jest serializowane.

Ale czy naprawdę tego potrzebujesz? NAPRAWDĘ?

Jeśli tak, to prawdopodobnie będziesz musiał użyć XmlSerializer dla tego procesu serializacji zamiast - nie można uzyskać większą kontrolę nad jak rzeczy są w odcinkach (ale jako wadzie, XmlSerializer będzie każdą własność publiczną, że nie jest serializacji wyraźnie oznaczone atrybutem [XmlIgnore] - schemat "rezygnacji").

Zapoznaj się z blog post Dan Rigsby na temat różnic między DataContractSerializer i XmlSerializer i co każdy z nich ma do zaoferowania.

+0

Chcę to serializować wszystkie właściwości, XMLSerializer nie jest nawet opcja, ponieważ mój obiekt ma IList w nim. Pytałem o schemat nazewnictwa, ponieważ byłoby łatwiej w moich dokumentach transformacji, gdyby właściwości dokładnie pasowały do ​​moich obiektów klasy. –

+0

czy udekorowałeś swoją klasę i właściwości atrybutami [DataMember]? Możesz zdefiniować nazwę z tymi: [DataMember (Name = "xyz")] - czy to pomoże w twoim przypadku? –

+0

czy udekorowałeś klasy, które znajdą się w twoim IList za pomocą atrybutu [DataContract] i [DataMember]? Wygląda to prawie tak, jakbyś nie ... –

5

Długie nazwy elementów (takie jak _x003C_Created_x003E_k__BackingField) są tworzone przez .NET, gdy używasz autoproperties.

Jeśli zmieniono je na właściwości z polami kopii, użyłyby one zamiast tego twoich nazw pól. Możesz to zrobić bez dodawania żadnych atrybutów do kodu.

(Poza tym, po prostu dodając [DataContract] atrybut do definicji klasy będzie uporządkować swoją XML dużo - choć nie do końca).

+0

Będę musiał sprawdzić, co sprawia, że ​​różnica, mogę zaakceptować umieszczenie atrybutu na poziomie klasy, zwłaszcza, że ​​te klasy są datacontracts, nawet jeśli nie są odsłonięte przez WCF –

+1

Jestem zainteresowany twoim doświadczeniem. Serializacja wydaje się słabo zdefiniowana i cierpi z powodu wielu rozwiązań. –

0

Poznałem ten sam problem, w końcu, więc wystarczy dodać [DataContract] 和 [DataMember] do modelu.

+1

Ta odpowiedź została automatycznie oznaczona jako niskiej jakości ze względu na jej długość i zawartość. [Krótkowzroczność jest akceptowalna, ale pełniejsze wyjaśnienia są lepsze.] (Http://stackoverflow.com/help/how-to-answer) –

Powiązane problemy