|
14 | 14 | using Microsoft.Extensions.ObjectPool;
|
15 | 15 | using Moq;
|
16 | 16 | using Newtonsoft.Json;
|
| 17 | +using Newtonsoft.Json.Converters; |
17 | 18 | using Newtonsoft.Json.Serialization;
|
18 | 19 | using Xunit;
|
19 | 20 |
|
20 | 21 | namespace Microsoft.AspNetCore.Mvc.Formatters
|
21 | 22 | {
|
22 | 23 | public class NewtonsoftJsonInputFormatterTest : JsonInputFormatterTestBase
|
23 | 24 | {
|
24 |
| - private static readonly ObjectPoolProvider _objectPoolProvider = new DefaultObjectPoolProvider(); |
25 |
| - private static readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings(); |
| 25 | + private readonly ObjectPoolProvider _objectPoolProvider = new DefaultObjectPoolProvider(); |
| 26 | + private readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings(); |
26 | 27 |
|
27 | 28 | [Fact]
|
28 | 29 | public async Task Constructor_BuffersRequestBody_UsingDefaultOptions()
|
@@ -144,7 +145,7 @@ public void Constructor_UsesSerializerSettings()
|
144 | 145 | var serializerSettings = new JsonSerializerSettings();
|
145 | 146 |
|
146 | 147 | // Act
|
147 |
| - var formatter = new TestableJsonInputFormatter(serializerSettings); |
| 148 | + var formatter = new TestableJsonInputFormatter(serializerSettings, _objectPoolProvider); |
148 | 149 |
|
149 | 150 | // Assert
|
150 | 151 | Assert.Same(serializerSettings, formatter.SerializerSettings);
|
@@ -185,7 +186,7 @@ public void CreateJsonSerializer_UsesJsonSerializerSettings()
|
185 | 186 | MaxDepth = 2,
|
186 | 187 | DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
|
187 | 188 | };
|
188 |
| - var formatter = new TestableJsonInputFormatter(settings); |
| 189 | + var formatter = new TestableJsonInputFormatter(settings, _objectPoolProvider); |
189 | 190 |
|
190 | 191 | // Act
|
191 | 192 | var actual = formatter.CreateJsonSerializer(null);
|
@@ -304,7 +305,7 @@ public async Task ReadAsync_DoNotAllowInputFormatterExceptionMessages_DoesNotWra
|
304 | 305 | }
|
305 | 306 |
|
306 | 307 | [Fact]
|
307 |
| - public async Task ReadAsync_lowInputFormatterExceptionMessages_DoesNotWrapJsonInputExceptions() |
| 308 | + public async Task ReadAsync_AllowInputFormatterExceptionMessages_DoesNotWrapJsonInputExceptions() |
308 | 309 | {
|
309 | 310 | // Arrange
|
310 | 311 | var formatter = new NewtonsoftJsonInputFormatter(
|
@@ -336,10 +337,72 @@ public async Task ReadAsync_lowInputFormatterExceptionMessages_DoesNotWrapJsonIn
|
336 | 337 | Assert.NotEmpty(modelError.ErrorMessage);
|
337 | 338 | }
|
338 | 339 |
|
| 340 | + [Fact] |
| 341 | + public async Task ReadAsync_DoesNotRethrowFormatExceptions() |
| 342 | + { |
| 343 | + // Arrange |
| 344 | + _serializerSettings.Converters.Add(new IsoDateTimeConverter()); |
| 345 | + |
| 346 | + var formatter = new NewtonsoftJsonInputFormatter( |
| 347 | + GetLogger(), |
| 348 | + _serializerSettings, |
| 349 | + ArrayPool<char>.Shared, |
| 350 | + _objectPoolProvider, |
| 351 | + new MvcOptions(), |
| 352 | + new MvcNewtonsoftJsonOptions()); |
| 353 | + |
| 354 | + var contentBytes = Encoding.UTF8.GetBytes("{\"dateValue\":\"not-a-date\"}"); |
| 355 | + var httpContext = GetHttpContext(contentBytes); |
| 356 | + |
| 357 | + var formatterContext = CreateInputFormatterContext(typeof(TypeWithPrimitives), httpContext); |
| 358 | + |
| 359 | + // Act |
| 360 | + var result = await formatter.ReadAsync(formatterContext); |
| 361 | + |
| 362 | + // Assert |
| 363 | + Assert.True(result.HasError); |
| 364 | + Assert.False(formatterContext.ModelState.IsValid); |
| 365 | + |
| 366 | + var modelError = Assert.Single(formatterContext.ModelState["dateValue"].Errors); |
| 367 | + Assert.Null(modelError.Exception); |
| 368 | + Assert.Equal("The supplied value is invalid.", modelError.ErrorMessage); |
| 369 | + } |
| 370 | + |
| 371 | + [Fact] |
| 372 | + public async Task ReadAsync_DoesNotRethrowOverflowExceptions() |
| 373 | + { |
| 374 | + // Arrange |
| 375 | + _serializerSettings.Converters.Add(new IsoDateTimeConverter()); |
| 376 | + |
| 377 | + var formatter = new NewtonsoftJsonInputFormatter( |
| 378 | + GetLogger(), |
| 379 | + _serializerSettings, |
| 380 | + ArrayPool<char>.Shared, |
| 381 | + _objectPoolProvider, |
| 382 | + new MvcOptions(), |
| 383 | + new MvcNewtonsoftJsonOptions()); |
| 384 | + |
| 385 | + var contentBytes = Encoding.UTF8.GetBytes("{\"shortValue\":\"32768\"}"); |
| 386 | + var httpContext = GetHttpContext(contentBytes); |
| 387 | + |
| 388 | + var formatterContext = CreateInputFormatterContext(typeof(TypeWithPrimitives), httpContext); |
| 389 | + |
| 390 | + // Act |
| 391 | + var result = await formatter.ReadAsync(formatterContext); |
| 392 | + |
| 393 | + // Assert |
| 394 | + Assert.True(result.HasError); |
| 395 | + Assert.False(formatterContext.ModelState.IsValid); |
| 396 | + |
| 397 | + var modelError = Assert.Single(formatterContext.ModelState["shortValue"].Errors); |
| 398 | + Assert.Null(modelError.Exception); |
| 399 | + Assert.Equal("The supplied value is invalid.", modelError.ErrorMessage); |
| 400 | + } |
| 401 | + |
339 | 402 | private class TestableJsonInputFormatter : NewtonsoftJsonInputFormatter
|
340 | 403 | {
|
341 |
| - public TestableJsonInputFormatter(JsonSerializerSettings settings) |
342 |
| - : base(GetLogger(), settings, ArrayPool<char>.Shared, _objectPoolProvider, new MvcOptions(), new MvcNewtonsoftJsonOptions()) |
| 404 | + public TestableJsonInputFormatter(JsonSerializerSettings settings, ObjectPoolProvider objectPoolProvider) |
| 405 | + : base(GetLogger(), settings, ArrayPool<char>.Shared, objectPoolProvider, new MvcOptions(), new MvcNewtonsoftJsonOptions()) |
343 | 406 | {
|
344 | 407 | }
|
345 | 408 |
|
@@ -418,5 +481,26 @@ private sealed class UserLogin
|
418 | 481 | [JsonProperty(Required = Required.Always)]
|
419 | 482 | public string Password { get; set; }
|
420 | 483 | }
|
| 484 | + |
| 485 | + public class TypeWithPrimitives |
| 486 | + { |
| 487 | + public DateTime DateValue { get; set; } |
| 488 | + |
| 489 | + [JsonConverter(typeof(IncorrectShortConverter))] |
| 490 | + public short ShortValue { get; set; } |
| 491 | + } |
| 492 | + |
| 493 | + private class IncorrectShortConverter : JsonConverter<short> |
| 494 | + { |
| 495 | + public override short ReadJson(JsonReader reader, Type objectType, short existingValue, bool hasExistingValue, JsonSerializer serializer) |
| 496 | + { |
| 497 | + return short.Parse(reader.Value.ToString()); |
| 498 | + } |
| 499 | + |
| 500 | + public override void WriteJson(JsonWriter writer, short value, JsonSerializer serializer) |
| 501 | + { |
| 502 | + throw new NotImplementedException(); |
| 503 | + } |
| 504 | + } |
421 | 505 | }
|
422 | 506 | }
|
0 commit comments