Ensure UnsupportedContentTypeFilter runs before ModelStateInvalidFilter

Both UnsupportedContentTypeFilter and ModelStateInvalidFilter use ModelState to
determine the response. UnsupportedContentTypeFilter returns a more specific
response and should execute earlier than the latter filter.

Fixes #8236
This commit is contained in:
Pranav K 2018-08-09 10:03:10 -07:00
parent da1189e6f1
commit 9da8e2c908
2 changed files with 44 additions and 2 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
@ -10,8 +11,16 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// <see cref="ActionContext.ModelState"/> and short-circuits the pipeline
/// with an Unsupported Media Type (415) response.
/// </summary>
public class UnsupportedContentTypeFilter : IActionFilter
public class UnsupportedContentTypeFilter : IActionFilter, IOrderedFilter
{
/// <summary>
/// Gets or sets the filter order. <see cref="IOrderedFilter.Order"/>.
/// <para>
/// Defaults to <c>-3000</c> to ensure it executes before <see cref="ModelStateInvalidFilter"/>.
/// </para>
/// </summary>
public int Order { get; set; } = -3000;
/// <inheritdoc />
public void OnActionExecuting(ActionExecutingContext context)
{
@ -32,7 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
foreach (var kvp in modelState)
{
var errors = kvp.Value.Errors;
for (int i = 0; i < errors.Count; i++)
for (var i = 0; i < errors.Count; i++)
{
var error = errors[i];
if (error.Exception is UnsupportedContentTypeException)

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using BasicWebSite.Models;
using Newtonsoft.Json;
@ -58,6 +59,38 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
);
}
[Fact]
public async Task ActionsReturnUnsupportedMediaType_WhenMediaTypeIsNotSupported()
{
// Arrange
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/contact")
{
Content = new StringContent("some content", Encoding.UTF8, "text/css"),
};
// Act
var response = await Client.SendAsync(requestMessage);
// Assert
await response.AssertStatusCodeAsync(HttpStatusCode.UnsupportedMediaType);
}
[Fact]
public async Task ActionsReturnUnsupportedMediaType_WhenEncodingIsUnsupported()
{
// Arrange
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/contact")
{
Content = new StringContent("some content", Encoding.UTF7, "application/json"),
};
// Act
var response = await Client.SendAsync(requestMessage);
// Assert
await response.AssertStatusCodeAsync(HttpStatusCode.UnsupportedMediaType);
}
[Fact]
public async Task ActionsReturnBadRequest_UsesProblemDescriptionProviderAndApiConventionsToConfigureErrorResponse()
{