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,29 @@ 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
+ { JTokenType . Bytes , typeof ( Byte ) } ,
49
+ } ;
50
+
28
51
/// <inheritdoc />
29
52
public virtual IDictionary < string , object > LoadTempData ( [ NotNull ] HttpContext context )
30
53
{
@@ -45,6 +68,26 @@ public virtual IDictionary<string, object> LoadTempData([NotNull] HttpContext co
45
68
{
46
69
tempDataDictionary = _jsonSerializer . Deserialize < Dictionary < string , object > > ( writer ) ;
47
70
}
71
+ foreach ( var item in tempDataDictionary . ToList ( ) )
72
+ {
73
+ var jArrayValue = item . Value as JArray ;
74
+ if ( jArrayValue != null && jArrayValue . Count > 0 )
75
+ {
76
+ Type returnType = null ;
77
+ _arrayTypeLookup . TryGetValue ( jArrayValue [ 0 ] . Type , out returnType ) ;
78
+ if ( returnType != null )
79
+ {
80
+ var arrayConverter = _arrayConverters . GetOrAdd ( returnType , type =>
81
+ {
82
+ return ( Func < JArray , object > ) Delegate . CreateDelegate ( typeof ( Func < JArray , object > ) ,
83
+ _convertArrayMethodInfo . MakeGenericMethod ( type ) ) ;
84
+ } ) ;
85
+ var result = arrayConverter ( jArrayValue ) ;
86
+
87
+ tempDataDictionary [ item . Key ] = result ;
88
+ }
89
+ }
90
+ }
48
91
49
92
// If we got it from Session, remove it so that no other request gets it
50
93
session . Remove ( TempDataSessionStateKey ) ;
@@ -104,8 +147,7 @@ internal void EnsureObjectCanBeSerialized(object item)
104
147
}
105
148
else if ( itemType . GetTypeInfo ( ) . IsGenericType )
106
149
{
107
- if ( itemType . ExtractGenericInterface ( typeof ( IList < > ) ) != null ||
108
- itemType . ExtractGenericInterface ( typeof ( IDictionary < , > ) ) != null )
150
+ if ( itemType . ExtractGenericInterface ( typeof ( IList < > ) ) != null )
109
151
{
110
152
actualTypes = itemType . GetGenericArguments ( ) ;
111
153
}
@@ -124,5 +166,10 @@ internal void EnsureObjectCanBeSerialized(object item)
124
166
}
125
167
}
126
168
}
169
+
170
+ private static IList < TVal > ConvertArray < TVal > ( JArray array )
171
+ {
172
+ return array . Values < TVal > ( ) . ToArray ( ) ;
173
+ }
127
174
}
128
175
}
0 commit comments