Jak usunąć k__BackingField z json podczas deserializacji


104

Otrzymuję k_BackingField w zwróconym jsonie po serializacji pliku xml do obiektu c # .net.

Dodałem DataContract i atrybut DataMember do obiektu c # .net, ale potem nic nie widzę po stronie json, po stronie klienta.

[XmlRoot("person")]
[Serializable]
public class LinkedIn
{
    [XmlElement("id")]
    public string ID { get; set; }

    [XmlElement("industry")]
    public string Industry { get; set; }

    [XmlElement("first-name")]
    public string FirstName { get; set; }

    [XmlElement("last-name")]
    public string LastName { get; set; }
    [XmlElement("headline")]
}

Przykład zwróconego pliku json:

home: Object
<FirstName>k__BackingField: "Storefront"
<LastName>k__BackingField: "Doors"

Odpowiedzi:


45

W rzeczywistości składnia właściwości automatycznej nie jest zalecana, jeśli klasa może być używana w serializacji. Powód, dla którego pole zapasowe jest generowane przez kompilator, może być inny za każdym razem, gdy kompilowany jest kod. Może to powodować problemy ze zgodnością, nawet jeśli w klasie nie zostanie wprowadzona żadna zmiana (wystarczy ponowna kompilacja kodu).

Myślę, że zastosowanie atrybutu DataMember rozwiąże problem w tym przypadku. Ale zalecałbym użycie pełnej składni właściwości, jeśli klasa ma być używana w serializacji.


Lol, zaimplementował długą wersję i ustawił prywatne pola na klienta.home: Object _fName: "Storefront" _headline: "CEO at StorefrontDoors.NET" _id: "" _industry: ""
Wypełnianie stosu jest tym, co robię

21
dodając ten zapis danych na początek klasy i element datamember do każdej właściwości, która mnie interesuje.
Wypełnianie stosu jest tym, co robię

3
@ AlumCloud.Com +1 dla [DataContract] i [DataMember]. Nie zapomnij dodać: System.Runtime.Serialization
Ian Newland

109

Usuń [Serializable]z zajęć


2
Teraz zastanawiam się, dlaczego myślałem, że potrzebuję programu [Serializable] w pierwszej kolejności. Moja serializacja Xml działa bez niego, a JSON działa bez niego.
Rhyous

11
To nie działa z usługami WCF. Podczas zwracania ładunku przy użyciu usług RESTful nie daje to żadnych danych, jeśli usuniesz [Serializable]. Dodaj System.Runtime.Serialization i użyj [DataContract] dla klasy, [DataMember] dla właściwości.
Ian Newland

Ta odpowiedź ORAZ komentarz Iana wydaje się obejmować oba przypadki. Do WCF czy nie do WCF, oto jest pytanie.
granadaCoder

1
@Rhyous - w Web API nie potrzebujesz [Serializable], ponieważ Web API jest skonfigurowane przy założeniu, że będziesz serializować i zwracać swoje obiekty (ponieważ to w zasadzie cała idea) - w innych aplikacjach C # zazwyczaj wymaga serializacji, aby rozróżniać obiekty, które można serializować
Jon Story

Dziękuję, utknąłem [Serializable], więc dodanie pól pomocniczych pomogło.
ohmusama,

59

Domyślny serializator WebApi doda składnię „__BackingField:” do właściwości automatycznych języka C #. Dodaj to do swojej konsoli WebConfig w App_Start, aby uzyskać bardziej przejrzysty plik JSON, którego możesz szukać.

using Newtonsoft.Json;
...

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();

3
To rozwiązało problem. Myślę, że właściwości auto są czyste. Używanie pól pomocniczych wszędzie wydaje się głupie. i wprowadza dużo bałaganu, a czasem zamieszania.
Romesh D. Niriella

To zadziałało dla mnie. W moim przypadku miałem istniejącą klasę, która była już używana przez usługi sieciowe WCF i ASMX, więc nie mogłem po prostu zmienić jej dla mojego nowego projektu WebAPI.
samiup

4
Pytanie brzmi, dlaczego serializator WebApi doda domyślnie to „__BackingField:”?
Teoman shipahi

dobre rozwiązanie. w moim przypadku muszę użyć [Serializable] save do memcache. Wymagane jest serializowanie.
Bình Nguyễn Quang

2
Co bym zrobił bez StackOverflow? Dzięki.
camainc

35

Mamy pewne obiekty, które są oznaczone jako [Serializable]tak, aby można je było serializować przy użyciu tradycyjnych metod, ale które musimy czysto serializować w formacie JSON do użytku z interfejsem API sieci Web. Ustawienie IgnoreSerializableAttributena truepowstrzyma Newtonsoft.Json przed zachowaniem się jak serialisers Microsoftu, a zamiast tego po prostu serializuje właściwości publiczne.

TLDR: Dodaj to do WebApiConfig.cs:

((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

Moderator: Zamiast usuwać naprawdę dobrą odpowiedź na pytanie, które zostało zadane kilka razy, usuń zduplikowane pytanie. To jest prawidłowa odpowiedź na ważne pytanie.


3
To powinna być właściwa odpowiedź. Usunięcie serializacji lub użycie atrybutów datacontract i datamember nie zawsze jest właściwym rozwiązaniem.
Houssam Hamdan

Wielu z nas, w tym OP, nie używa Webapi, MVVM, ani czegokolwiek, o co wam chodzi. Co to jest app_start i webapiconfig, gdy mam normalną usługę WCF mydła z service.svc?
Christian,

10

Prosty, łatwy i przyzwoity sposób na ujawnienie danych Musimy udostępnić dane w obiekcie w czytelnym i spójnym formacie


Najpierw usuń [serializowalny]

    [Serializable]

teraz dodaj [DataContract] w klasie i [DataMember] dla właściwości jak w poniższym przykładzie

[DataContract]
public class UserDiscretion : UserReport
{
    [DataMember]
    public String DiscretionCode { get; set; }
    public String DiscretionDescription { get; set; }
}

Mam nadzieję, że ta pomoc
dzięki.


1
W przypadku korzystania z interfejsu API sieci Web nie ma potrzeby dodawania atrybutów DataContract i DataMember - wystarczy zwrócić obiekt, a zostanie on zserializowany automatycznie.
Jon Story

Jeśli ktoś zaczyna programowanie od zera, to świetnie będzie skorzystać z interfejsu API sieci Web, który zapewni zwracany typ Object, nie będzie wymagał żadnego typu rzutowania do ujawnienia klientowi. Ale jeśli chodzi o pytanie @ AlumCloud.com, jeśli jest w istniejącej aplikacji, więc rozwiązanie jego problemu będzie przez Najpierw usuń [Serializable], a następnie dodaj [DataContract] w klasie i [DataMember] dla nieruchomości jak poniżej, jak sugerowano
Nagendra Upwanshi

1
Dodaje to ogromną ilość „szumu” do twoich zajęć i jest zasadniczo niepotrzebne (zobacz wszystkie inne komentarze). Jeśli jednak ktoś czuje potrzebę zrobienia tego, zalecałbym użycie czegoś takiego jak PostSharp, aby dodać kod podczas kompilacji, aby nie zaśmiecał twoich klas wszystkimi tymi atrybutami.
camainc

7

Kilka opcji:

  1. Usuń [Serializable]z modelu

  2. Dodaj [DataContract]i [DataMember]do swojego modelu wraz z [Serializable]

  3. Dodaj poniższą linię do App_Start/WebApiConfig.cs

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();

3

Kolejne rozwiązanie, które może pomóc w przypadku JSON.NET. Wystarczy oznaczyć klasę atrybutem [Newtonsoft.Json.JsonObject].

Pracowałem z klasami cs zbudowanymi z xsd i dodawałem niektóre właściwości za pomocą klas częściowych. Po serializacji json te właściwości zostały oznaczone k_BackingField. Ustawienia JsonFormatter wspomniane w innych odpowiedziach również pomogły, ale prostsze było oznaczenie częściowej klasy atrybutem [JsonObject].


2

Używałem DataContractJsonSerializerz klasą z innego zestawu, który miał Serializableatrybut. Dane wyjściowe zawierały „k__BackingField”. Usunięcie Serializableatrybutu (w innym zestawie) naprawiło ten problem. Nie pewny dlaczego.


0

Zakładając, że widzisz ten problem w swoim projekcie MVC, stwierdziłem, że zastąpienie użycia @ Html.JsonData jest całkiem proste. Oto fragment kodu, który działał dla mnie w przeszłości:

<input type="hidden" id="Model" value="@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model))" />

Nie tak eleganckie, ale proste w mgnieniu oka.


0

Wystąpił ten problem, gdy w mojej klasie są właściwości odniesienia do siebie, takie jak;

class Person {
 List<Person> Friends { get; set;}
}

I był rezultat, osoba była ze sobą zaprzyjaźniona. Po prostu upewniłem się, że w moim zestawie wyników nie ma obiektów odwołujących się do siebie. Mam nadzieję że to pomoże.



0

w moim przypadku ten błąd był dla wersji Newtonsoft.Json, serwer szukał wersji 6.0.0 i miałem 11.0 więc musiałem zainstalować wersję 6.0.0


-2

Przyjaciele, nie deklarujcie takich właściwości:

public String DiscretionCode { get; set; }
public String DiscretionDescription { get; set; }

Ale stwórz pomocnicze zmienne, takie jak stare ...

private String discretionCode;

public String DiscretionCode 
{ 
    get { return discretionCode;}
    set { discretionCode = value; }
}

1
Czemu? Czy mógłbyś dać rezonans?
Lucenty

@Lucenty daje taki kod JSON ... [{"discationCode": "x"}] podczas serializacji.
Ammar Ameerdeen

Ale tego bym się spodziewał - tak serializuje dane JSON. I myślę, że kod z pomocniczymi zmiennymi da ten sam wynik.
Lucenty,

Dodano k_BackingField, aby wskazać, że właściwość automatyczna została zserializowana. Jeśli zmienisz właściwość auto na właściwość i pole zapasowe, problem zniknie. Myślę, że w tym wątku są lepsze rozwiązania, ale to działa.
timB33
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.