2013-08-19 1 views
4

У меня есть класс некоторых вещей, как показано нижекогда мы сериализовать сериализуемый объект с помощью Json.NET, JSON строка отличается от DatacontractJSON сериализатора

[Serializable] 
public class sample 
{ 
    private int m_width; 
    private int m_height; 
    public int Width 
    { 
     get 
     { 
      return this.m_width; 
     } 
     set 
     { 
      this.m_width = value; 
     } 
    } 

    public int Height 
    { 

     get 
     { 
      return this.m_height; 
     } 
     set 
     { 
      this.m_height = value; 
     } 
    } 
} 

Если я использую DataContractJsonSerializer для сериализации объекта этого класса я получаю json строка, как показано ниже:

{"m_height":1345,"m_width":1234} 

Если я использую Newtonsoft.Json.dll сериализовать это я получаю из положить, как показано ниже:

{"Width":1234,"Height":1345} 

Почему DataContractSerializer использует поля поддержки для сериализации, если класс помечен как сериализуемый?

Есть ли способ, что я могу достичь того же с помощью Newtonsoft.Json.dll

+3

«? Почему это класс, используя отступающие поля, если свойства не являются нестандартными» Может быть, еще один разумный вопрос. –

+0

http://forums.asp.net/p/1400518/3039466.aspx – I4V

ответ

1

Класс DefaultContractResolver в Newtonsoft.Json.dll я нашел код, который устанавливает свойство IgnoreSerializableAttribute в значение true.

#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) 
    IgnoreSerializableAttribute = true; 
#endif 

Я использую DLL DotNet4.0 так это свойство установлено в истинное и игнорирование Serializable атрибута. если я делаю его ложным, он дает тот же результат, что и DataContractSerializer

+0

Для WebAPI, I добавил этот WebApiConfig.cs: \t \t \t ((Newtonsoft.Json.Serialization.DefaultContractResolver) config.Formatters.JsonFormatter.SerializerSettings.ContractResolver) .IgnoreSerializableAttribute = TRUE; – Richard

1

Если вы не всегда общение с WCF на WCF, лучше всего, вероятно, будет использовать сериалайзер Newtonsoft. К сожалению, сериализатор MS, похоже, соответствует определенным стандартам Microsoft, которые не соответствуют стандартам, которые ожидают многие веб-приложения.

Сериализатор Newtonsoft выглядит более стандартным, и даже MS использует его для WebAPI и в http-клиенте веб-API (nuget вытащит его для вас).

Вот еще одно отличие, которое вы найдете - попробуйте сериализовать тип DateTime. Вы обнаружите, что серийный диск DataContract сериализует значение в другом формате, который несовместим с другим JSON (вы заметите некоторые сокращения в нем). Я понимаю, что этот альтернативный формат использовался некоторыми элементами управления AJAX WebForm, но он специфичен для Microsoft Webforms.

Вот немного больше информации о датах: http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx

1

Вот еще одна вещь, которую вы можете посмотреть по адресу:

Различия между DataContractJsonSerializer и Newtonsoft до сих пор стоят, но почему вы получаете странное поведение сериализации - вы смешиваете свои стандарты сериализации.

Атрибут [Serializable] относится к более ранней сериализации .Net. DataContractSerialization обратно совместима, но поведение может быть другим.

Если вы хотите сделать это методом datacontract, отметьте класс с атрибутом [DataContract] и отметьте каждый публичный член, который вы хотите сериализовать, с атрибутом [DataMember]. (или удалить все атрибуты сериализации, и он должен по умолчанию использовать все общедоступные свойства)

Это должно объяснить разницу, которая видна, но я бы по-прежнему рекомендовал вам использовать сериализатор Newtonsoft.

0

DataContract serializer требует, чтобы явным образом маркировал класс с атрибутом [DataContract], а затем маркировал каждое требуемое свойство, которое должно быть сериализовано с помощью атрибута [DataMember].

Если вы это сделаете, вы обнаружите, что одна и та же строка json выйдет из использования другого класса. вопрос вы столкнулись из-за различий в том, как 2 сериализаторов лечения сериализации по умолчанию (без дополнительной информации, указанной):

  1. DataContract упорядочивает все частные поля, если не указано иное

  2. NewtonSoft Сериализует все общественные свойства если не указано иное

О том, как сделать Newtonsoft сериализацией частных полей, у меня нет другой идеи, кроме создания класса-оболочки с свойствами m_Width и m_Height, которые на сеттерах и получателях помещают значения в правильные целевые свойства фактического объекта.

+0

ваш answser кажется неправильным, если я удаляю атрибут сериализации в классе, DatacontractSerializer сериализует публичные поля вместо полей поддержки –

2

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

TLDR: Добавить это WebApiConfig.cs:

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