Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit 994c831

Browse files
committed
addressed feedback
1 parent db1b708 commit 994c831

File tree

6 files changed

+149
-18
lines changed

6 files changed

+149
-18
lines changed

src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Microsoft.AspNet.Mvc.Core/Resources.resx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,6 @@
452452
<value>The model's runtime type '{0}' is not assignable to the type '{1}'.</value>
453453
</data>
454454
<data name="TempData_CannotSerializeToSession" xml:space="preserve">
455-
<value>The type {0} cannot be serialized to Session.</value>
455+
<value>The type {0} cannot be serialized to Session by '{1}'.</value>
456456
</data>
457457
</root>

src/Microsoft.AspNet.Mvc.Core/SessionStateTempDataProvider.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ namespace Microsoft.AspNet.Mvc
1717
/// </summary>
1818
public class SessionStateTempDataProvider : ITempDataProvider
1919
{
20-
private string TempDataSessionStateKey = "__ControllerTempData";
21-
private JsonSerializer jsonSerializer = new JsonSerializer();
20+
private const string TempDataSessionStateKey = "__ControllerTempData";
21+
private readonly JsonSerializer _jsonSerializer = JsonSerializer.Create(
22+
new JsonSerializerSettings()
23+
{
24+
TypeNameHandling = TypeNameHandling.Auto
25+
});
2226

2327
/// <inheritdoc />
2428
public virtual IDictionary<string, object> LoadTempData([NotNull] HttpContext context)
@@ -38,7 +42,7 @@ public virtual IDictionary<string, object> LoadTempData([NotNull] HttpContext co
3842
using (var memoryStream = new MemoryStream(value))
3943
using (var writer = new BsonReader(memoryStream))
4044
{
41-
tempDataDictionary = jsonSerializer.Deserialize<Dictionary<string, object>>(writer);
45+
tempDataDictionary = _jsonSerializer.Deserialize<Dictionary<string, object>>(writer);
4246
}
4347

4448
// If we got it from Session, remove it so that no other request gets it
@@ -60,7 +64,7 @@ public virtual void SaveTempData([NotNull] HttpContext context, IDictionary<stri
6064
var hasValues = (values != null && values.Count > 0);
6165
if (hasValues)
6266
{
63-
// We want to allow only primitive types to be serialized in session.
67+
// We want to allow only simple types to be serialized in session.
6468
EnsureObjectCanBeSerialized(values);
6569

6670
// Accessing Session property will throw if the session middleware is not enabled.
@@ -69,7 +73,7 @@ public virtual void SaveTempData([NotNull] HttpContext context, IDictionary<stri
6973
using (var memoryStream = new MemoryStream())
7074
using (var writer = new BsonWriter(memoryStream))
7175
{
72-
jsonSerializer.Serialize(writer, values);
76+
_jsonSerializer.Serialize(writer, values);
7377
session[TempDataSessionStateKey] = memoryStream.ToArray();
7478
}
7579
}
@@ -85,7 +89,7 @@ private bool IsSessionEnabled(HttpContext context)
8589
return context.GetFeature<ISessionFeature>() != null;
8690
}
8791

88-
private void EnsureObjectCanBeSerialized(IDictionary<string, object> values)
92+
internal void EnsureObjectCanBeSerialized(IDictionary<string, object> values)
8993
{
9094
foreach (var item in values.Values)
9195
{
@@ -108,7 +112,8 @@ private void EnsureObjectCanBeSerialized(IDictionary<string, object> values)
108112
var underlyingType = Nullable.GetUnderlyingType(actualType) ?? actualType;
109113
if (!TypeHelper.IsSimpleType(actualType))
110114
{
111-
var message = Resources.FormatTempData_CannotSerializeToSession(underlyingType);
115+
var message = Resources.FormatTempData_CannotSerializeToSession(underlyingType,
116+
typeof(SessionStateTempDataProvider).FullName);
112117
throw new InvalidOperationException(message);
113118
}
114119
}

test/Microsoft.AspNet.Mvc.Core.Test/SessionStateTempDataProviderTest.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,29 @@ public void Save_NullSession_NonEmptyDictionary_Throws()
7878

7979
[Theory]
8080
[MemberData(nameof(InvalidTypes))]
81-
public void Save_InvalidType_Throws(string key, object value, Type type)
81+
public void EnsureObjectCanBeSerialized_InvalidType_Throws(string key, object value, Type type)
8282
{
8383
// Arrange
8484
var testProvider = new SessionStateTempDataProvider();
8585

8686
// Act & Assert
8787
var exception = Assert.Throws<InvalidOperationException>(() =>
8888
{
89-
testProvider.SaveTempData(
90-
GetHttpContext(session: null, sessionEnabled: false),
91-
new Dictionary<string, object> { { key, value } }
92-
);
89+
testProvider.EnsureObjectCanBeSerialized(new Dictionary<string, object> { { key, value } });
9390
});
94-
Assert.Equal(string.Format("The type {0} cannot be serialized to Session.", type), exception.Message);
91+
Assert.Equal($"The type {type} cannot be serialized to Session by '{typeof(SessionStateTempDataProvider).FullName}'.",
92+
exception.Message);
93+
}
94+
95+
[Theory]
96+
[MemberData(nameof(ValidTypes))]
97+
public void EnsureObjectCanBeSerialized_ValidType_DoesNotThrow(string key, object value)
98+
{
99+
// Arrange
100+
var testProvider = new SessionStateTempDataProvider();
101+
102+
// Act & Assert (Does not throw)
103+
testProvider.EnsureObjectCanBeSerialized(new Dictionary<string, object> { { key, value } });
95104
}
96105

97106
public static TheoryData<string, object, Type> InvalidTypes
@@ -109,6 +118,22 @@ public static TheoryData<string, object, Type> InvalidTypes
109118
}
110119
}
111120

121+
public static TheoryData<string, object> ValidTypes
122+
{
123+
get
124+
{
125+
return new TheoryData<string, object>
126+
{
127+
{ "int", 10 },
128+
{ "IntArray", new int[]{ 10, 20 } },
129+
{ "string", "FooValue" },
130+
{ "SimpleDict", new Dictionary<string, int>() },
131+
{ "Uri", new Uri("http://Foo") },
132+
{ "Guid", Guid.NewGuid() },
133+
};
134+
}
135+
}
136+
112137
private class TestItem
113138
{
114139
public int DummyInt { get; set; }

test/Microsoft.AspNet.Mvc.FunctionalTests/TempDataTest.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,61 @@ public async Task Peek_RetainsTempData()
140140
Assert.Equal("Foo", body);
141141
}
142142

143+
[Fact]
144+
public async Task TempData_ValidTypes_RoundTripProperly()
145+
{
146+
// Arrange
147+
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
148+
var client = server.CreateClient();
149+
var testGuid = Guid.NewGuid();
150+
var nameValueCollection = new List<KeyValuePair<string, string>>
151+
{
152+
new KeyValuePair<string, string>("value", "Foo"),
153+
new KeyValuePair<string, string>("intValue", "10"),
154+
new KeyValuePair<string, string>("listValues", "Foo1"),
155+
new KeyValuePair<string, string>("listValues", "Foo2"),
156+
new KeyValuePair<string, string>("listValues", "Foo3"),
157+
new KeyValuePair<string, string>("datetimeValue", "10/10/2010"),
158+
new KeyValuePair<string, string>("guidValue", testGuid.ToString()),
159+
};
160+
var content = new FormUrlEncodedContent(nameValueCollection);
161+
162+
// Act 1
163+
var redirectResponse = await client.PostAsync("/Home/SetTempDataMultiple", content);
164+
165+
// Assert 1
166+
Assert.Equal(HttpStatusCode.Redirect, redirectResponse.StatusCode);
167+
168+
// Act 2
169+
var response = await client.SendAsync(GetRequest(redirectResponse.Headers.Location.ToString(), redirectResponse));
170+
171+
// Assert 2
172+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
173+
var body = await response.Content.ReadAsStringAsync();
174+
Assert.Equal($"Foo 10 3 10/10/2010 00:00:00 {testGuid.ToString()}", body);
175+
}
176+
177+
[Fact]
178+
public async Task TempData_InvalidType_Throws()
179+
{
180+
// Arrange
181+
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
182+
var client = server.CreateClient();
183+
var nameValueCollection = new List<KeyValuePair<string, string>>
184+
{
185+
new KeyValuePair<string, string>("value", "Foo"),
186+
};
187+
var content = new FormUrlEncodedContent(nameValueCollection);
188+
189+
// Act & Assert
190+
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
191+
{
192+
await client.PostAsync("/Home/SetTempDataInvalidType", content);
193+
});
194+
Assert.Equal("The type " + typeof(TempDataWebSite.Controllers.HomeController.NonSerializableType).FullName +
195+
" cannot be serialized to Session by '" + typeof(SessionStateTempDataProvider).FullName + "'.", exception.Message);
196+
}
197+
143198
private HttpRequestMessage GetRequest(string path, HttpResponseMessage response)
144199
{
145200
var request = new HttpRequestMessage(HttpMethod.Get, path);

test/WebSites/TempDataWebSite/Controllers/HomeController.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
5+
using System.Collections.Generic;
46
using Microsoft.AspNet.Mvc;
57

68
namespace TempDataWebSite.Controllers
@@ -41,5 +43,49 @@ public IActionResult PeekTempData()
4143
var peekValue = TempData.Peek("key");
4244
return Content(peekValue.ToString());
4345
}
46+
47+
public IActionResult SetTempDataMultiple(
48+
string value,
49+
int intValue,
50+
IList<string> listValues,
51+
DateTime datetimeValue,
52+
Guid guidValue)
53+
{
54+
TempData["key1"] = value;
55+
TempData["key2"] = intValue;
56+
TempData["key3"] = listValues;
57+
TempData["key4"] = datetimeValue;
58+
TempData["key5"] = guidValue;
59+
return RedirectToAction("GetTempDataMultiple");
60+
}
61+
62+
public string GetTempDataMultiple()
63+
{
64+
var value1 = TempData["key1"].ToString();
65+
var value2 = Convert.ToInt32(TempData["key2"]);
66+
var value3 = (IList<string>)TempData["key3"];
67+
var value4 = (DateTime)TempData["key4"];
68+
var value5 = (Guid)TempData["key5"];
69+
return $"{value1} {value2.ToString()} {value3.Count.ToString()} {value4.ToString()} {value5.ToString()}";
70+
}
71+
72+
public string SetTempDataInvalidType()
73+
{
74+
var exception = "";
75+
try
76+
{
77+
TempData["key"] = new NonSerializableType();
78+
}
79+
catch (Exception e)
80+
{
81+
exception = e.Message;
82+
}
83+
84+
return exception;
85+
}
86+
87+
public class NonSerializableType
88+
{
89+
}
4490
}
4591
}

0 commit comments

Comments
 (0)