/// <inheritdoc /> public virtual IDictionary<string, object> LoadTempData(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // Accessing Session property will throw if the session middleware is not enabled. var session = context.Session; var tempDataDictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); byte[] value; if (session.TryGetValue(TempDataSessionStateKey, out value)) { using (var memoryStream = new MemoryStream(value)) using (var writer = new BsonReader(memoryStream)) { tempDataDictionary = _jsonSerializer.Deserialize<Dictionary<string, object>>(writer); } var convertedDictionary = new Dictionary<string, object>( tempDataDictionary, StringComparer.OrdinalIgnoreCase); foreach (var item in tempDataDictionary) { var jArrayValue = item.Value as JArray; var jObjectValue = item.Value as JObject; if (jArrayValue != null && jArrayValue.Count > 0) { var arrayType = jArrayValue[0].Type; Type returnType; if (_tokenTypeLookup.TryGetValue(arrayType, out returnType)) { var arrayConverter = _arrayConverters.GetOrAdd(returnType, type => { return (Func<JArray, object>)_convertArrayMethodInfo .MakeGenericMethod(type) .CreateDelegate(typeof(Func<JArray, object>)); }); var result = arrayConverter(jArrayValue); convertedDictionary[item.Key] = result; } else { var message = Resources.FormatTempData_CannotDeserializeToken(nameof(JToken), arrayType); throw new InvalidOperationException(message); } } else if (jObjectValue != null) { if (!jObjectValue.HasValues) { convertedDictionary[item.Key] = null; continue; } var jTokenType = jObjectValue.Properties().First().Value.Type; Type valueType; if (_tokenTypeLookup.TryGetValue(jTokenType, out valueType)) { var dictionaryConverter = _dictionaryConverters.GetOrAdd(valueType, type => { return (Func<JObject, object>)_convertDictMethodInfo .MakeGenericMethod(type) .CreateDelegate(typeof(Func<JObject, object>)); }); var result = dictionaryConverter(jObjectValue); convertedDictionary[item.Key] = result; } else { var message = Resources.FormatTempData_CannotDeserializeToken(nameof(JToken), jTokenType); throw new InvalidOperationException(message); } } else if (item.Value is long) { var longValue = (long)item.Value; if (longValue < int.MaxValue) { // BsonReader casts all ints to longs. We'll attempt to work around this by force converting // longs to ints when there's no loss of precision. convertedDictionary[item.Key] = (int)longValue; } } } tempDataDictionary = convertedDictionary; // If we got it from Session, remove it so that no other request gets it session.Remove(TempDataSessionStateKey); } else { // Since we call Save() after the response has been sent, we need to initialize an empty session // so that it is established before the headers are sent. session.Set(TempDataSessionStateKey, new byte[] { }); } return tempDataDictionary; }