vb.net 使用 System.Web.Script.Serialization.JavaScriptSerializer 创建包含非公开/好友属性的 JSON 对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39328250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use System.Web.Script.Serialization.JavaScriptSerializer to create JSON object including Non-Public/Friend Properties
提问by Jamie Hartnoll
Simplified class model:
简化的类模型:
Class ShoppingBasket
Property Items as BasketItems()
.....
Class BasketItems
Property ItemName as string
Property ItemPrice as Decimal
Friend ItemCost as Decimal
....
End Class
This is obviously a shopping cart system.
这显然是一个购物车系统。
I want to be able to save a serialised string of this shopping basket into a database, simple code:
我希望能够将这个购物篮的序列化字符串保存到数据库中,简单代码:
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...
This code all runs fine, but I lose the Frienddeclared Property "ItemCost".
这段代码运行良好,但我丢失了Friend声明的属性“ItemCost”。
This class is used as the return property from an AJAX "Add to Cart" button, so I want the ItemCost property (and various others) to be hidden from the externalJavascript Console/Development Console in a User's Browser, but need to be able to internallysave and recover the full class data using the method above.
此类用作 AJAX“添加到购物车”按钮的返回属性,因此我希望 ItemCost 属性(以及其他各种属性)在用户浏览器的外部Javascript 控制台/开发控制台中隐藏,但需要能够到内部保存和恢复使用上述方法的全部类的数据。
So, how do I create a Friendproperty so that it can be Serialized when specifically serialized to a string by the JavaScriptSerilaizer class, but not, when it is returned (and internally serialized) by an AJAX POSTresponse?
那么,如何创建一个Friend属性,以便它可以在 JavaScriptSerilaizer 类专门序列化为字符串时进行序列化,但在 AJAXPOST响应返回(并在内部序列化)时则不能?
回答by dbc
As with XmlSerializer, JavaScriptSerializeronly serializes public properties and fields. There is no attribute like [DataMember]to force a non-public property to be serialized by JavaScriptSerializer.
与 一样XmlSerializer,JavaScriptSerializer仅序列化公共属性和字段。没有像[DataMember]强制非公共属性被序列化的属性JavaScriptSerializer。
Instead, you can create a JavaScriptConverterof Friendscope that serializes and deserializes all the public properties of BasketItemsautomatically, and adds the ItemCostalso:
相反,你可以创建一个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
And then use it like:
然后像这样使用它:
Dim JS as new System.Web.Script.Serialization.JavaScriptSerializer()
JS.RegisterConverters({ new ShoppingBasket.BasketItemsConverter() })
Dim BasketString = JS.Serialize(basket).ToString()
Alternatively, you could consider switching to json.netwhen serializing internally to a string, then marking your non-public properties with <JsonProperty>.
或者,您可以考虑在内部序列化为字符串时切换到json.net,然后使用<JsonProperty>.

