2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
4
using System ;
5
+ using System . Collections . Concurrent ;
5
6
using System . Collections . Generic ;
6
7
using System . IO ;
8
+ using System . Linq ;
7
9
using System . Reflection ;
8
10
using Microsoft . AspNet . Http ;
9
11
using Microsoft . AspNet . Mvc . Core ;
10
12
using Microsoft . Framework . Internal ;
11
13
using Newtonsoft . Json ;
12
14
using Newtonsoft . Json . Bson ;
15
+ using Newtonsoft . Json . Linq ;
13
16
14
17
namespace Microsoft . AspNet . Mvc
15
18
{
@@ -22,9 +25,28 @@ public class SessionStateTempDataProvider : ITempDataProvider
22
25
private readonly JsonSerializer _jsonSerializer = JsonSerializer . Create (
23
26
new JsonSerializerSettings ( )
24
27
{
25
- TypeNameHandling = TypeNameHandling . Auto
28
+ TypeNameHandling = TypeNameHandling . None
26
29
} ) ;
27
30
31
+ private static readonly MethodInfo _convertArrayMethodInfo = typeof ( SessionStateTempDataProvider ) . GetMethod (
32
+ nameof ( ConvertArray ) , BindingFlags . NonPublic | BindingFlags . Static , null , new [ ] { typeof ( JArray ) } , null ) ;
33
+
34
+ private readonly ConcurrentDictionary < Type , Func < JArray , object > > _arrayConverters =
35
+ new ConcurrentDictionary < Type , Func < JArray , object > > ( ) ;
36
+
37
+ private static Dictionary < JTokenType , Type > _arrayTypeLookup = new Dictionary < JTokenType , Type >
38
+ {
39
+ { JTokenType . String , typeof ( string ) } ,
40
+ { JTokenType . Integer , typeof ( int ) } ,
41
+ { JTokenType . Boolean , typeof ( bool ) } ,
42
+ { JTokenType . Float , typeof ( float ) } ,
43
+ { JTokenType . Guid , typeof ( Guid ) } ,
44
+ { JTokenType . Object , typeof ( object ) } ,
45
+ { JTokenType . Date , typeof ( DateTime ) } ,
46
+ { JTokenType . TimeSpan , typeof ( TimeSpan ) } ,
47
+ { JTokenType . Uri , typeof ( Uri ) } ,
48
+ } ;
49
+
28
50
/// <inheritdoc />
29
51
public virtual IDictionary < string , object > LoadTempData ( [ NotNull ] HttpContext context )
30
52
{
@@ -45,6 +67,26 @@ public virtual IDictionary<string, object> LoadTempData([NotNull] HttpContext co
45
67
{
46
68
tempDataDictionary = _jsonSerializer . Deserialize < Dictionary < string , object > > ( writer ) ;
47
69
}
70
+ foreach ( var item in tempDataDictionary . ToList ( ) )
71
+ {
72
+ var jArrayValue = item . Value as JArray ;
73
+ if ( jArrayValue != null && jArrayValue . Count > 0 )
74
+ {
75
+ Type returnType = null ;
76
+ _arrayTypeLookup . TryGetValue ( jArrayValue [ 0 ] . Type , out returnType ) ;
77
+ if ( returnType != null )
78
+ {
79
+ var arrayConverter = _arrayConverters . GetOrAdd ( returnType , type =>
80
+ {
81
+ return ( Func < JArray , object > ) Delegate . CreateDelegate ( typeof ( Func < JArray , object > ) ,
82
+ _convertArrayMethodInfo . MakeGenericMethod ( type ) ) ;
83
+ } ) ;
84
+ var result = arrayConverter ( jArrayValue ) ;
85
+
86
+ tempDataDictionary [ item . Key ] = result ;
87
+ }
88
+ }
89
+ }
48
90
49
91
// If we got it from Session, remove it so that no other request gets it
50
92
session . Remove ( TempDataSessionStateKey ) ;
@@ -104,8 +146,7 @@ internal void EnsureObjectCanBeSerialized(object item)
104
146
}
105
147
else if ( itemType . GetTypeInfo ( ) . IsGenericType )
106
148
{
107
- if ( itemType . ExtractGenericInterface ( typeof ( IList < > ) ) != null ||
108
- itemType . ExtractGenericInterface ( typeof ( IDictionary < , > ) ) != null )
149
+ if ( itemType . ExtractGenericInterface ( typeof ( IList < > ) ) != null )
109
150
{
110
151
actualTypes = itemType . GetGenericArguments ( ) ;
111
152
}
@@ -124,5 +165,10 @@ internal void EnsureObjectCanBeSerialized(object item)
124
165
}
125
166
}
126
167
}
168
+
169
+ private static IList < TVal > ConvertArray < TVal > ( JArray array )
170
+ {
171
+ return array . Values < TVal > ( ) . ToArray ( ) ;
172
+ }
127
173
}
128
174
}
0 commit comments