Как удалить k__BackingField из json при десериализации

104

Я получаю k_BackingField в моем возвращенном json после сериализации xml-файла в объект .net C #.

Я добавил DataContract и атрибут DataMember к объекту .net C #, но тогда я ничего не получаю на стороне клиента json.

[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")]
}

Пример возвращенного json:

home: Object
<FirstName>k__BackingField: "Storefront"
<LastName>k__BackingField: "Doors"
Заполнение стопки - вот что я делаю
источник

Ответы:

45

Синтаксис автоматического свойства на самом деле не рекомендуется, если класс можно использовать в сериализации. Причина, по которой резервное поле генерируется компилятором, которое может отличаться каждый раз при компиляции кода. Это может вызвать проблемы несовместимости, даже если в класс не вносятся изменения (просто перекомпиляция кода).

Я думаю, что применение атрибута DataMember решит проблему в этом случае. Но я бы рекомендовал использовать полный синтаксис свойств, если класс нужно использовать в сериализации.

зазубрины
источник
Лол, реализуемый длинную версию и установить частные поля к client.home: _fName объекта: «Storefront» _headline: «генеральный директор компании» StorefrontDoors.NET _ID: «» _industry: «»
Заполнение стека , что я делаю
21
добавление этого контракта данных в начало класса и элемента данных для каждого свойства, которое меня интересует, сработало.
Заполнение стопки - вот что я делаю
3
@ AlumCloud.Com +1 для [DataContract] и [DataMember]. Не забудьте добавить: System.Runtime.Serialization
Ян Ньюленд,
109

Удалить [Serializable]из вашего класса

Сафаа Эльгенди
источник
2
Теперь мне интересно, почему я вообще решил, что мне нужен [Serializable]. Моя сериализация Xml работает без нее, а JSON работает без нее.
Rhyous 03
11
Это не работает со службами WCF. При возврате полезной нагрузки с помощью служб RESTful это не дает никаких данных, если вы удалите [Serializable]. Добавьте System.Runtime.Serialization и используйте [DataContract] для класса, [DataMember] для свойств.
Ян Ньюленд
Этот ответ И комментарий Яна, кажется, охватывает оба случая. В WCF или не в WCF, вот в чем вопрос.
granadaCoder
1
@Rhyous - в веб-API вам не нужен [Serializable], потому что веб-API настроен с предположением, что вы собираетесь сериализовать и возвращать свои объекты (поскольку это в основном вся идея) - в других приложениях C # вы обычно нужен Serializable, чтобы различать сериализуемые объекты
Джон Стори
Спасибо, я застрял [Serializable], поэтому добавление вспомогательных полей помогло.
ohmusama 08
59

Сериализатор WebApi по умолчанию добавит этот синтаксис «__BackingField:» к автоматическим свойствам C #. Добавьте это в свой WebConfig в App_Start, чтобы получить более чистый на вид json, который вы, возможно, ищете.

using Newtonsoft.Json;
...

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
Дэн
источник
3
Это устранило проблему. Считаю авто свойства чистыми. Использование поддерживающих полей везде кажется глупым. и вносит много беспорядка, а иногда и путаницу.
Ромеш Д. Нириэлла
Это сработало для меня. В моем случае у меня был существующий класс, который уже использовался веб-службами WCF и ASMX, поэтому я не мог просто изменить его для своего нового проекта WebAPI.
samiup
4
Вопрос в том, почему сериализатор WebApi по умолчанию добавляет это «__BackingField:»?
Теоман Шипахи
хорошее решение. в моем случае мне нужно использовать [Serializable] для сохранения в кэш памяти. Требуется сериализуемый.
Bình Nguyễn Quang
2
Что бы я делал без StackOverflow? Спасибо.
camainc
35

У нас есть некоторые объекты, которые помечены как [Serializable]так, чтобы их можно было сериализовать с использованием традиционных методов, но которые нам нужно четко сериализовать в JSON для использования с веб-API. Установка IgnoreSerializableAttributeна trueостановит Newtonsoft.Json от поведения сериализаторов Microsoft, и вместо этого он просто сериализует общедоступные свойства.

TL; DR: добавьте это в WebApiConfig.cs:

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

Модератор: Вместо того, чтобы удалять действительно хороший ответ на вопрос, который задавали несколько раз, удалите повторяющийся вопрос. Это верный ответ на правильный вопрос.

Ричард
источник
3
Это должен быть правильный ответ. Удаление сериализации или использование атрибутов datacontract и datamember не всегда является правильным решением.
Хусам Хамдан,
Многие из нас, в том числе OP, не используют Webapi или MVVM или что-то еще, о чем вы, ребята, говорите. Что такое app_start и webapiconfig, когда у меня есть обычная мыльная служба WCF с service.svc?
Кристиан
10

Простой легкий и достойный способ предоставления данных Нам необходимо предоставить данные в объекте в легко читаемом и согласованном формате


Сначала удалите [Serializable]

    [Serializable]

теперь добавьте [DataContract] в класс и [DataMember] для свойства, как в примере ниже

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

Надеюсь на эту помощь.
Спасибо.

Нагендра Упванши
источник
1
При использовании веб-API нет необходимости добавлять атрибуты DataContract и DataMember - просто верните объект, и он будет сериализован автоматически.
Джон Стори
Если кто-то начинает разработку с нуля, было бы здорово использовать веб-API, который будет предоставлять тип возвращаемого объекта, не требующий какого-либо преобразования типа для предоставления клиенту. Но для вопроса @ AlumCloud.com, если он находится в существующем приложении, решение его проблемы будет: Сначала удалите [Serializable], затем добавьте [DataContract] в класс и [DataMember] для свойства, как показано ниже, как предлагается
Нагендра Упванши,
1
Это добавляет огромного количества «шума» к вашим классам и, по сути, не нужно (см. Все другие комментарии). Однако, если вы чувствуете необходимость это сделать, я бы рекомендовал использовать что-то вроде PostSharp, чтобы добавить код для вас во время компиляции, чтобы он не загромождал ваши классы всеми этими атрибутами.
camainc
7

Пара вариантов:

  1. Удалить [Serializable]из модели

  2. Добавьте [DataContract]и [DataMember]к своей модели вместе с [Serializable]

  3. Добавить строку ниже в App_Start/WebApiConfig.cs

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
Джаяпракаш Мутугопал
источник
3

Еще одно решение, которое может помочь в случае JSON.NET. Может быть достаточно отметить класс атрибутом [Newtonsoft.Json.JsonObject].

Я работал с классами cs, созданными из xsd, и добавлял некоторые свойства, используя частичные классы. После сериализации json эти свойства были отмечены k_BackingField. Настройки JsonFormatter, упомянутые в других ответах, также помогли, но более простым было отметить частичный класс атрибутом [JsonObject].

сарх
источник
2

Я использовал DataContractJsonSerializerс классом из другой сборки, у которой был Serializableатрибут. Вывод содержал «k__BackingField». Это Serializableисправлено удалением атрибута (в другой сборке). Не знаю почему.

Little Endian
источник
0

Предполагая, что вы видите эту проблему внутри своего проекта MVC, я обнаружил, что заменить использование @ Html.JsonData довольно просто. Вот фрагмент кода, который работал у меня в прошлом:

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

Не так элегантно, но в крайнем случае просто.

Райан Роарк
источник
0

У меня возникла эта проблема, когда в моем классе были свойства самосылки, например:

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

И вот результат, человек дружил сам с собой. Я просто удостоверился, что в моем наборе результатов нет объектов, ссылающихся на себя. Надеюсь это поможет.

Теоман Шипахи
источник
0

Мне пришлось использовать атрибуты [Serializable], поэтому их нельзя было удалить.

XmlSerializer игнорирует [XmlAttribute] в WebApi

Приведенное выше решение решило эту проблему для меня.

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
JanBorup
источник
0

в моем случае эта ошибка была для версии Newtonsoft.Json, сервер искал версию 6.0.0, а у меня была 11.0, поэтому мне пришлось установить версию 6.0.0

Андрес Гильен
источник
-2

Друзья, не объявляйте такие свойства:

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

Но создайте вспомогательные вары, например старые ....

private String discretionCode;

public String DiscretionCode 
{ 
    get { return discretionCode;}
    set { discretionCode = value; }
}
Умберто Гонсалвис де Алмейда
источник
1
Зачем? Не могли бы вы дать резонанс?
Lucenty
@Lucenty при сериализации дает такой JSON .. [{"discationCode": "x"}].
Аммар Амердин 08
Но это то, чего я ожидал - именно так JSON сериализует данные. И я думаю, что код с дополнительными варами даст такой же результат.
Lucenty
k_BackingField был добавлен, чтобы указать, что автоматическое свойство было сериализовано. Если вы измените автоматическое свойство на свойство и поле поддержки, проблема исчезнет. Я думаю, что в этой теме есть лучшие решения, но это работает.
timB33