Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,13 @@ public override async Task<InputFormatterResult> ReadRequestBodyAsync(

void ErrorHandler(object? sender, Newtonsoft.Json.Serialization.ErrorEventArgs eventArgs)
{
// Skipping error, if it's already marked as handled
// This allows user code to implement its own error handling
if (eventArgs.ErrorContext.Handled)
{
return;
}

successful = false;

// When ErrorContext.Path does not include ErrorContext.Member, add Member to form full path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,44 @@ public async Task ReadAsync_WithReadJsonWithRequestCulture_DeserializesUsingRequ
}
}

[Fact]
public async Task ReadAsync_AllowUserCodeToHandleDeserializationErrors()
{
// Arrange
var serializerSettings = new JsonSerializerSettings
{
Error = (sender, eventArgs) =>
{
eventArgs.ErrorContext.Handled = true;
}
};
var formatter = new NewtonsoftJsonInputFormatter(
GetLogger(),
serializerSettings,
ArrayPool<char>.Shared,
_objectPoolProvider,
new MvcOptions(),
new MvcNewtonsoftJsonOptions());

var content = $"{{'id': 'should be integer', 'name': 'test location'}}";
var contentBytes = Encoding.UTF8.GetBytes(content);
var httpContext = new DefaultHttpContext();
httpContext.Features.Set<IHttpResponseFeature>(new TestResponseFeature());
httpContext.Request.Body = new NonSeekableReadStream(contentBytes, allowSyncReads: false);
httpContext.Request.ContentType = "application/json";

var formatterContext = CreateInputFormatterContext(typeof(Location), httpContext);

// Act
var result = await formatter.ReadAsync(formatterContext);

// Assert
Assert.False(result.HasError);
var location = (Location)result.Model;
Assert.Equal(0, location?.Id);
Assert.Equal("test location", location?.Name);
}

private class TestableJsonInputFormatter : NewtonsoftJsonInputFormatter
{
public TestableJsonInputFormatter(JsonSerializerSettings settings, ObjectPoolProvider objectPoolProvider)
Expand Down