diff --git a/src/Microsoft.AspNetCore.Mvc.Abstractions/Filters/ResourceExecutingContext.cs b/src/Microsoft.AspNetCore.Mvc.Abstractions/Filters/ResourceExecutingContext.cs
index 34b96c96e3..770acb2bd2 100644
--- a/src/Microsoft.AspNetCore.Mvc.Abstractions/Filters/ResourceExecutingContext.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Abstractions/Filters/ResourceExecutingContext.cs
@@ -2,15 +2,11 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
-using Microsoft.AspNetCore.Mvc.Formatters;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
namespace Microsoft.AspNetCore.Mvc.Filters
{
///
- /// A context for resource filters. Allows modification of services and values used for
- /// model binding.
+ /// A context for resource filters.
///
public class ResourceExecutingContext : FilterContext
{
@@ -23,34 +19,14 @@ namespace Microsoft.AspNetCore.Mvc.Filters
: base(actionContext, filters)
{
}
-
- ///
- /// Gets or sets the list of instances used by model binding.
- ///
- public virtual FormatterCollection InputFormatters { get; set; }
-
- ///
- /// Gets or sets the list of instances used by model binding.
- ///
- public virtual IList ModelBinders { get; set; }
-
+
///
/// Gets or sets the result of the action to be executed.
///
///
/// Setting to a non-null value inside a resource filter will
- /// short-circuit execution of additional resource filtes and the action itself.
+ /// short-circuit execution of additional resource filters and the action itself.
///
public virtual IActionResult Result { get; set; }
-
- ///
- /// Gets or sets the list of instances used by model binding.
- ///
- public IList ValueProviderFactories { get; set; }
-
- ///
- /// Gets or sets the list of instances used by model binding.
- ///
- public IList ValidatorProviders { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/FilterActionInvoker.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/FilterActionInvoker.cs
index 3a9ab93d62..a81f0febce 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/FilterActionInvoker.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/FilterActionInvoker.cs
@@ -255,15 +255,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{
_cursor.Reset();
- var context = new ResourceExecutingContext(Context, _filters);
-
- context.InputFormatters = new FormatterCollection(
- new CopyOnWriteList(_inputFormatters));
- context.ModelBinders = new CopyOnWriteList(_modelBinders);
- context.ValidatorProviders = new CopyOnWriteList(_modelValidatorProviders);
- context.ValueProviderFactories = new CopyOnWriteList(_valueProviderFactories);
-
- _resourceExecutingContext = context;
+ _resourceExecutingContext = new ResourceExecutingContext(Context, _filters);
return InvokeResourceFilterAsync();
}
@@ -362,16 +354,17 @@ namespace Microsoft.AspNetCore.Mvc.Internal
{
// We've reached the end of resource filters, so move to setting up state to invoke model
// binding.
- Context.InputFormatters = _resourceExecutingContext.InputFormatters;
- Context.ModelBinders = _resourceExecutingContext.ModelBinders;
- Context.ValidatorProviders = _resourceExecutingContext.ValidatorProviders;
+ Context.InputFormatters = new FormatterCollection(
+ new CopyOnWriteList(_inputFormatters));
+ Context.ModelBinders = new CopyOnWriteList(_modelBinders);
+ Context.ValidatorProviders = new CopyOnWriteList(_modelValidatorProviders);
var valueProviders = new List();
var factoryContext = new ValueProviderFactoryContext(Context);
- for (var i = 0; i < _resourceExecutingContext.ValueProviderFactories.Count; i++)
+ for (var i = 0; i < _valueProviderFactories.Count; i++)
{
- var factory = _resourceExecutingContext.ValueProviderFactories[i];
+ var factory = _valueProviderFactories[i];
await factory.CreateValueProviderAsync(factoryContext);
}
Context.ValueProviders = factoryContext.ValueProviders;
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs
index de5b720615..516031ea03 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/BasicTests.cs
@@ -350,34 +350,5 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
-
- [Fact]
- public async Task ResourceFilter_CreatesSpecificInputAndOutputFormatters()
- {
- // Arrange
- var input = "{\"fullName\":\"John Doe\"}";
-
- // Act
- var response = await Client.PostAsync(
- "http://localhost/api/ActionUsingSpecificFormatters",
- new StringContent(input, Encoding.UTF8, "application/json"));
-
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal(input, await response.Content.ReadAsStringAsync());
-
- // Make sure it does not affect other actions
- //Arrange
- input = "{\"FullName\":\"John Doe\"}";
-
- // Act
- response = await Client.PostAsync(
- "http://localhost/api/ActionUsingGlobalFormatters",
- new StringContent(input, Encoding.UTF8, "application/json"));
-
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal(input, await response.Content.ReadAsStringAsync());
- }
}
}
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/FiltersTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/FiltersTest.cs
index 9b0ba5a8fa..5d68855e51 100644
--- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/FiltersTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/FiltersTest.cs
@@ -509,58 +509,5 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
Assert.Equal("\"someValue\"", await response.Content.ReadAsStringAsync());
}
-
- [Fact]
- public async Task ResourceFilter_ChangesOutputFormatters_JsonReturned()
- {
- // Arrange
- var input = "{ sampleInt: 10 }";
- var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Json");
- request.Content = new StringContent(input, Encoding.UTF8, "application/json");
-
- // Act
- var response = await Client.SendAsync(request);
-
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType);
- Assert.Equal("\"10\"", await response.Content.ReadAsStringAsync());
- }
-
- [Fact]
- public async Task ResourceFilter_ChangesInputFormatters_JsonAccepted()
- {
- // Arrange
- var input = "{ sampleInt: 10 }";
- var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Json");
- request.Content = new StringContent(input, Encoding.UTF8, "application/json");
-
- // Act
- var response = await Client.SendAsync(request);
-
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal("\"10\"", await response.Content.ReadAsStringAsync());
- }
-
- [Fact]
- public async Task ResourceFilter_ChangesInputFormatters_XmlDenied()
- {
- // Arrange
- var input =
- "" +
- "10" +
- "";
-
- // There's nothing that can deserialize the body, so the result is UnsupportedMediaType.
- var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Json");
- request.Content = new StringContent(input, Encoding.UTF8, "application/xml");
-
- // Act
- var response = await Client.SendAsync(request);
-
- // Assert
- Assert.Equal(HttpStatusCode.UnsupportedMediaType, response.StatusCode);
- }
}
}
\ No newline at end of file
diff --git a/test/WebSites/BasicWebSite/Controllers/SpecificFormattersController.cs b/test/WebSites/BasicWebSite/Controllers/SpecificFormattersController.cs
deleted file mode 100644
index ce802de203..0000000000
--- a/test/WebSites/BasicWebSite/Controllers/SpecificFormattersController.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.AspNetCore.Mvc.Formatters;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Serialization;
-
-namespace BasicWebSite
-{
- public class SpecificFormattersController : Controller
- {
- [HttpPost("api/ActionUsingSpecificFormatters")]
- [CamelCaseJsonFormatters]
- public IActionResult ActionUsingSpecificFormatters([FromBody] Person person)
- {
- if (!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
-
- return Ok(person);
- }
-
- [HttpPost("api/ActionUsingGlobalFormatters")]
- public IActionResult ActionUsingGlobalFormatters([FromBody] Person person)
- {
- if (!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
-
- return Ok(person);
- }
-
- public class Person
- {
- public string FullName { get; set; }
- }
-
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
- private class CamelCaseJsonFormattersAttribute : Attribute, IResourceFilter, IResultFilter
- {
- private readonly JsonSerializerSettings _serializerSettings;
-
- public CamelCaseJsonFormattersAttribute()
- {
- _serializerSettings = new JsonSerializerSettings();
- _serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
- }
-
- public void OnResourceExecuted(ResourceExecutedContext context)
- {
- }
-
- public void OnResourceExecuting(ResourceExecutingContext context)
- {
- // Do not modify existing json formatters as they would effect all controllers.
- // Instead remove and add new formatters which only effects the controllers this
- // attribute is decorated on.
- context.InputFormatters.RemoveType();
- var loggerFactory = context.HttpContext.RequestServices.GetRequiredService();
- var logger = loggerFactory.CreateLogger();
- context.InputFormatters.Add(new JsonInputFormatter(logger ,_serializerSettings));
- }
-
- public void OnResultExecuted(ResultExecutedContext context)
- {
- }
-
- public void OnResultExecuting(ResultExecutingContext context)
- {
- var objectResult = context.Result as ObjectResult;
- if (objectResult != null)
- {
- objectResult.Formatters.RemoveType();
- objectResult.Formatters.Add(new JsonOutputFormatter(_serializerSettings));
- }
- }
- }
- }
-}
diff --git a/test/WebSites/FiltersWebSite/Controllers/JsonOnlyController.cs b/test/WebSites/FiltersWebSite/Controllers/JsonOnlyController.cs
deleted file mode 100644
index 5957e233db..0000000000
--- a/test/WebSites/FiltersWebSite/Controllers/JsonOnlyController.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Linq;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.AspNetCore.Mvc.Formatters;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
-
-namespace FiltersWebSite.Controllers
-{
- [JsonOnly]
- [Route("Json")]
- public class JsonOnlyController : Controller
- {
- [HttpPost]
- public string Post([FromBody] DummyClass dummy)
- {
- return (dummy?.SampleInt ?? 0).ToString();
- }
-
- private class JsonOnlyAttribute : Attribute, IResultFilter
- {
- public void OnResourceExecuted(ResourceExecutedContext context)
- {
- }
-
- public void OnResourceExecuting(ResourceExecutingContext context)
- {
- // InputFormatters collection contains JsonInputFormatter and JsonPatchInputFormatter. Picking
- // JsonInputFormatter by matching the type exactly rather than using OfType.
- var jsonFormatter = context.InputFormatters.OfType()
- .Where(t => t.GetType() == typeof(JsonInputFormatter)).FirstOrDefault();
-
- context.InputFormatters.Clear();
- context.InputFormatters.Add(jsonFormatter);
- }
-
- public void OnResultExecuted(ResultExecutedContext context)
- {
- }
-
- public void OnResultExecuting(ResultExecutingContext context)
- {
- // Update the output formatter collection to only return JSON.
- if (context.Result is ObjectResult)
- {
- var options = context.HttpContext.RequestServices.GetRequiredService>();
- var jsonFormatter = options.Value.OutputFormatters.OfType().Single();
- var result = (ObjectResult)context.Result;
- result.Formatters.Add(jsonFormatter);
- }
- }
- }
- }
-}
\ No newline at end of file