2016-09-05 3 views
0

Упрощенная модель класса:Использование System.Web.Script.Serialization.JavaScriptSerializer создать объект JSON, включая Non-Public/Friend Свойства

Class ShoppingBasket 
    Property Items as BasketItems() 
    ..... 
    Class BasketItems 
     Property ItemName as string 
     Property ItemPrice as Decimal 
     Friend ItemCost as Decimal 
     .... 
    End Class 

Это, очевидно, корзина системы.

Я хочу, чтобы иметь возможность сохранить упорядоченную строку этой корзины в базу данных, простой код:

Dim basket as new ShoppingBasket 
Dim BasketString as string 
Dim JS as new System.Web.Script.Serialization.JavaScriptSerializer 

BasketString = JS.Serialize(basket).ToString() 

.... now save BasketString into the database... 

Этот код все работает нормально, но я потерять Friend объявил собственности «ItemCost».

Этот класс используется как свойство возвращения из AJAX «Добавить в корзину» кнопки, так что я хочу свойство ItemCost (и различные другие) должны быть скрыты от внешнего Javascript консоли/консоли развития в браузере пользователя , но должен иметь возможность внутренне сохранять и восстанавливать полные данные класса, используя метод выше.

Итак, как создать Friend свойства, так что он может быть Сериализированным, когда конкретно сериализованным в строку класса JavaScriptSerilaizer, но, когда она возвращается (и внутренне сериализованная) с помощью AJAX POST ответа?

ответ

0

Как и в случае с XmlSerializer, JavaScriptSerializer сериализует публичные объекты и поля. Нет такого атрибута, как [DataMember], чтобы заставить непубличное свойство сериализоваться на JavaScriptSerializer.

Вместо этого, вы можете создать JavaScriptConverter из Friend сферы, которые сериализующий и Десериализует все общественные свойства BasketItems автоматически, и добавляет ItemCost также:

Imports System.Web.Script.Serialization 

Public Class ShoppingBasket 
    Public Property Items as BasketItems() 

    Public Class BasketItems 
     Public Property ItemName as string 
     Public Property ItemPrice as Decimal 
     Friend ItemCost as Decimal 
    End Class 

    Friend Class BasketItemsConverter 
     Inherits JavaScriptConverter 
     Const ItemCostName As String = "ItemCost" 

     Public Overrides Function Deserialize(dictionary As IDictionary(Of String, Object), type As Type, serializer As JavaScriptSerializer) As Object 
      ' Perform a default deserialization for public properties. 
      Dim myObj = New JavaScriptSerializer().ConvertToType(Of BasketItems)(dictionary) 
      Dim itemCost As Object 
      If dictionary.TryGetValue(ItemCostName, itemCost) AndAlso itemCost IsNot Nothing Then 
       myObj.ItemCost = serializer.ConvertToType(Of Decimal)(itemCost) 
      End If 
      Return myObj 
     End Function 

     Public Overrides Function Serialize(obj As Object, serializer As JavaScriptSerializer) As IDictionary(Of String, Object) 
      ' Generate a default serialization for public properties. Is there an easier way to do this? 
      Dim defaultSerializer = New JavaScriptSerializer() 
      Dim dict = defaultSerializer.Deserialize(Of Dictionary(Of String, Object))(defaultSerializer.Serialize(obj)) 

      Dim basketItem = DirectCast(obj, BasketItems) 
      dict(ItemCostName) = basketItem.ItemCost 

      Return dict 
     End Function 

     Public Overrides ReadOnly Property SupportedTypes() As IEnumerable(Of Type) 
      Get 
       Return { GetType(BasketItems) } 
      End Get 
     End Property 
    End Class  
End Class 

, а затем использовать это нравится:

Dim JS as new System.Web.Script.Serialization.JavaScriptSerializer() 
JS.RegisterConverters({ new ShoppingBasket.BasketItemsConverter() })     

Dim BasketString = JS.Serialize(basket).ToString() 

В качестве альтернативы можно было бы переключиться на при сериализации внутри строки, а затем пометить ваши непубличные свойства <JsonProperty>.

Смежные вопросы