gpt4 book ai didi

c# - 如何在自定义 session 状态提供程序中将 session 数据转换为 SessionStateStoreData 类型

转载 作者:行者123 更新时间:2023-11-30 21:57:34 24 4
gpt4 key购买 nike

我在我的 Web 应用程序中使用了一个自定义 session 提供程序,它继承了 SessionStateStoreProviderBase 和重写方法。用于从 session 中获取数据的方法的返回类型为 SessionStateStoreData

目前二进制序列化被用于序列化和反序列化数据。我想使用 json 序列化 而不是二进制,但不确定如何将 session 数据(json 序列化后的字符串类型)转换为 SessionStateStoreData 类型。 SessionStateStoreData 类型的构造函数使用 SessionStateItemCollection 类型对象,该对象可以从 sessionstateitemcollection 的反序列化方法中获取,该方法仅将二进制流作为输入。

var ms = _serializedSessionData == null
? new MemoryStream()
: new MemoryStream(_serializedSessionData);

var sessionItems = new SessionStateItemCollection();

if (ms.Length > 0)
{
var reader = new BinaryReader(ms);
sessionItems = SessionStateItemCollection.Deserialize(reader);
}

return new SessionStateStoreData(sessionItems,
SessionStateUtility.GetSessionStaticObjects(context),
_timeout);

我附上了用于二进制反序列化的代码。如何对 json 序列化对象做同样的事情?

最佳答案

A SessionStateItemCollection 非常接近 Dictionary<string, object> ,所以你可以这样序列化它。但是,您需要考虑 null 的可能性。 key 。 null SessionStateItemCollection 允许 key 但是Dictionary<string, object>将在空键上抛出异常。

由于 SessionStateItemCollection 中的值是无类型的,您还需要一个支持序列化任意类型的类型信息的 JSON 序列化程序。 Json.NET可以做到这一点。 JavaScriptSerializer 也可以。 DataContractJsonSerializer 可能是合适的,因为您必须事先知道所有可能的类型并将它们传递给 constructor作为已知类型。

对于剩下的答案,我假设您选择了 Json.NET。

首先定义如下中间类用于序列化:

public class StringDictionaryWrapper
{
public StringDictionaryWrapper()
{
Items = new Dictionary<string, object>();
}

// Holds the value of the item with a null key, if any.
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto, DefaultValueHandling = DefaultValueHandling.Ignore)]
public object NullItem { get; set; }

[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
public Dictionary<string, object> Items { get; set; }
}

然后,序列化一个SessionStateItemCollection到一个 json 字符串,做:

        var dict = new StringDictionaryWrapper { Items = sessionItems.Keys.OfType<string>().ToDictionary(key => key, key => sessionItems[key]), NullItem = sessionItems[null] };
var json = JsonConvert.SerializeObject(dict, Formatting.Indented);

JSON 看起来像这样:

{
"NullItem": 1123,
"Items": {
"foo": {
"$type": "Question30640792.SomeClass, Tile",
"SomeProperty": "foo2"
},
"TestClass": {
"$type": "Question30640792.TestClass, Tile",
"A": 101,
"B": 102
}
}
}

要从 json 字符串反序列化,请执行以下操作:

        var sessionItems = new SessionStateItemCollection();

var dict = JsonConvert.DeserializeObject<StringDictionaryWrapper>(json);
if (dict != null && dict.NullItem != null)
sessionItems[null] = dict.NullItem;
if (dict != null && dict.Items != null)
foreach (var pair in dict.Items)
sessionItems[pair.Key] = pair.Value;

请注意,这将立即反序列化所有 session 状态项的整个集合,而内置二进制序列化使用 on-demand deserialization for performance reasons .因此,您可能会看到性能下降。此外,由于 Dictionary<TKey, TValue> 是无序的, session 项可能不会以与原来相同的顺序返回。如果这是一个问题,您可能需要创建类似这样的东西 custom proxy wrapper用于您的 session 项目集合。

最后,当使用 TypeNameHandling 时, 请注意 Newtonsoft docs 中的警告:

TypeNameHandling should be used with caution when your application deserializes JSON from an external source. Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.

有关为什么这可能是必要的讨论,请参阅 TypeNameHandling caution in Newtonsoft Json .

关于c# - 如何在自定义 session 状态提供程序中将 session 数据转换为 SessionStateStoreData 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30640792/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com