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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 20:03:19  来源:igfitidea点击:

Use System.Web.Script.Serialization.JavaScriptSerializer to create JSON object including Non-Public/Friend Properties

jsonvb.netserializationjavascriptserializer

提问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.

与 一样XmlSerializerJavaScriptSerializer仅序列化公共属性和字段。没有像[DataMember]强制非公共属性被序列化的属性JavaScriptSerializer

Instead, you can create a JavaScriptConverterof Friendscope that serializes and deserializes all the public properties of BasketItemsautomatically, and adds the ItemCostalso:

相反,你可以创建一个JavaScriptConverterFriend范围是序列化和反序列化所有的公共属性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>.