如何将具有私有属性的对象存储到asp.net核心会话中?

时间:2016-11-08 19:53:47

标签: asp.net-core asp.net-core-mvc asp.net-core-1.0 coreclr

我有下面的对象

public class MyObject
{
   private IEnumerable _data;
   public MyObject(IEnumerable<int> data)
   {
     _data = data;
   }

   public IEnumerable GetData()
   {
     return this._data;
   }
}

_data属性是私有的。我使用jsonserializer

将此对象存储在会话中,如下所示
 var val = new MyObject(new int[] {1,2,3})
 HttpContext.Session.SetString("MyKey", JsonConvert.SerializeObject(val));

然后我试图检索它如下

     var val = HttpContext.Session.GetString("MyKey");
     var myObject = JsonConvert.DeserializeObject<MyObject>(val);

但是MyObject.GetData()返回null。我假设_data属性是私有的JsonSerializer无法序列化它。
那么我有什么选择在会话中存储具有私有属性的对象?

2 个答案:

答案 0 :(得分:1)

您可以尝试使您的类可以像这样序列化

[Serializable]
public class MyObject : ISerializable
{
    private IEnumerable _data;
    public MyObject(IEnumerable<int> data)
    {
        _data = data;
    }

    public IEnumerable GetData()
    {
        return this._data;
    }

    protected MyObject(SerializationInfo info, StreamingContext context)
    {
        _data = (IEnumerable<int>)info.GetValue(nameof(_data), typeof(IEnumerable<int>));
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException(nameof(info));

        info.AddValue(nameof(_data), _data, typeof(IEnumerable<int>));
    }
}

为此,您必须至少定位netstandard1.3(.NET Framework 4.6或.NET Core)。在project.json中,您需要添加System.Runtime.Serialization.Formatters依赖项

"netstandard1.3": {
  "imports": [ "dnxcore50", "portable-net45+win8" ],
  "dependencies": {
    "NETStandard.Library": "1.6.0",
    "System.Runtime.Serialization.Formatters": "4.0.0-rc3-24212-01"
  }
}

我没有在.NET Core上测试它,所以不知道它是否有效。但这是你实现的方式,但JSON.NET实际上支持序列化ISerializable个对象。我只是不知道JSON.NET的.NET Core版本是否支持它,因为nuget package目标netstandard1.0ISerializable需要System.Runtime.Serialization.Formatters,这需要{{1} }}

答案 1 :(得分:0)

我认为这是标准的JSON.Net序列化问题。除非您按this answer中的规定提供自己的序列化程序,否则私有属性不会被序列化。

此外,您需要一个默认构造函数,或者确保正确标记您的构造函数(不确定它是否适用于私有字段)。 This是非默认构造函数问题的一个很好的答案。

我觉得你的班级是一个简单的DTO,没有太多保持这个领域私密的价值。为什么不把它标记为公开?或者,如果您的对象比给定的示例更复杂,您可能希望拥有一个仅具有公共属性的专用DTO,而不是仅为序列化/反序列化创建的功能,然后手动转换为您实际需要的类。这样,即使您在其他类中引入了重大更改,也可以确保在发布新版本时DTO保持兼容。