diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionContext.cs b/src/Microsoft.AspNet.Mvc.Core/ActionContext.cs
index ff754b235c..8720abf600 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ActionContext.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ActionContext.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.ModelBinding;
@@ -39,6 +40,12 @@ namespace Microsoft.AspNet.Mvc
public ModelStateDictionary ModelState { get; private set; }
public ActionDescriptor ActionDescriptor { get; private set; }
+
+ ///
+ /// Input formatters associated with this context.
+ /// The formatters are populated only after IInputFormattersProvider runs.
+ ///
+ public IList InputFormatters { get; set; }
///
/// The controller is available only after the controller factory runs.
diff --git a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs
index f7215f0148..d30b8c7b71 100644
--- a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs
@@ -240,16 +240,10 @@ namespace Microsoft.AspNet.Mvc
var modelMetadata = metadataProvider.GetMetadataForType(
modelAccessor: null,
modelType: parameterType);
- var providerContext = new InputFormatterProviderContext(
- actionBindingContext.ActionContext,
- modelMetadata,
- modelState);
-
- var inputFormatter = actionBindingContext.InputFormatterProvider.GetInputFormatter(
- providerContext);
-
var formatterContext = new InputFormatterContext(actionBindingContext.ActionContext,
modelMetadata.ModelType);
+ var inputFormatter = actionBindingContext.InputFormatterSelector.SelectFormatter(
+ formatterContext);
parameterValues[parameter.Name] = await inputFormatter.ReadAsync(formatterContext);
}
else
diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultInputFormatterSelector.cs
similarity index 54%
rename from src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs
rename to src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultInputFormatterSelector.cs
index e91321d963..fb5ff4a577 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultInputFormatterSelector.cs
@@ -6,32 +6,22 @@ using System.Globalization;
namespace Microsoft.AspNet.Mvc
{
- public class TempInputFormatterProvider : IInputFormatterProvider
+ public class DefaultInputFormatterSelector : IInputFormatterSelector
{
- private IInputFormattersProvider _defaultFormattersProvider;
-
- public TempInputFormatterProvider([NotNull] IInputFormattersProvider formattersProvider)
+ public IInputFormatter SelectFormatter(InputFormatterContext context)
{
- _defaultFormattersProvider = formattersProvider;
- }
-
- public IInputFormatter GetInputFormatter(InputFormatterProviderContext context)
- {
- var request = context.ActionContext.HttpContext.Request;
- var formatterContext = new InputFormatterContext(context.ActionContext,
- context.Metadata.ModelType);
-
// TODO: https://github.com/aspnet/Mvc/issues/1014
- var formatters = _defaultFormattersProvider.InputFormatters;
+ var formatters = context.ActionContext.InputFormatters;
foreach (var formatter in formatters)
{
- var formatterMatched = formatter.CanRead(formatterContext);
- if (formatterMatched)
+ if (formatter.CanRead(context))
{
return formatter;
}
}
+ var request = context.ActionContext.HttpContext.Request;
+
// TODO: https://github.com/aspnet/Mvc/issues/458
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture,
"415: Unsupported content type {0}",
diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/IInputFormatterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/IInputFormatterSelector.cs
similarity index 73%
rename from src/Microsoft.AspNet.Mvc.Core/Formatters/IInputFormatterProvider.cs
rename to src/Microsoft.AspNet.Mvc.Core/Formatters/IInputFormatterSelector.cs
index f46073dc07..4450a6618d 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Formatters/IInputFormatterProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/IInputFormatterSelector.cs
@@ -9,8 +9,8 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc
{
- public interface IInputFormatterProvider
+ public interface IInputFormatterSelector
{
- IInputFormatter GetInputFormatter(InputFormatterProviderContext context);
+ IInputFormatter SelectFormatter(InputFormatterContext context);
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatterProviderContext.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatterProviderContext.cs
deleted file mode 100644
index 68c4bf1ed7..0000000000
--- a/src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatterProviderContext.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Microsoft.AspNet.Http;
-using Microsoft.AspNet.Mvc.ModelBinding;
-
-namespace Microsoft.AspNet.Mvc
-{
- public class InputFormatterProviderContext
- {
- public InputFormatterProviderContext([NotNull] ActionContext actionContext,
- [NotNull] ModelMetadata metadata,
- [NotNull] ModelStateDictionary modelState)
- {
- ActionContext = actionContext;
- Metadata = metadata;
- ModelState = modelState;
- }
-
- public ActionContext ActionContext { get; private set; }
-
- public ModelMetadata Metadata { get; private set; }
-
- public ModelStateDictionary ModelState { get; private set; }
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
index b317439e0f..bf56da758e 100644
--- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
@@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Mvc
///
/// Get a list of the which are used to construct
- /// a list of by .
+ /// a list of by .
///
public List InputFormatters { get; private set; }
diff --git a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs
index 232dc05dbb..cf5047179c 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs
@@ -12,14 +12,14 @@ namespace Microsoft.AspNet.Mvc
IModelMetadataProvider metadataProvider,
IModelBinder modelBinder,
IValueProvider valueProvider,
- IInputFormatterProvider inputFormatterProvider,
+ IInputFormatterSelector inputFormatterSelector,
IEnumerable validatorProviders)
{
ActionContext = context;
MetadataProvider = metadataProvider;
ModelBinder = modelBinder;
ValueProvider = valueProvider;
- InputFormatterProvider = inputFormatterProvider;
+ InputFormatterSelector = inputFormatterSelector;
ValidatorProviders = validatorProviders;
}
@@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc
public IValueProvider ValueProvider { get; private set; }
- public IInputFormatterProvider InputFormatterProvider { get; private set; }
+ public IInputFormatterSelector InputFormatterSelector { get; private set; }
public IEnumerable ValidatorProviders { get; private set; }
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/DefaultActionBindingContextProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/DefaultActionBindingContextProvider.cs
index 9600fcbde3..dcadab07ee 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/DefaultActionBindingContextProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/DefaultActionBindingContextProvider.cs
@@ -13,20 +13,20 @@ namespace Microsoft.AspNet.Mvc
private readonly IModelMetadataProvider _modelMetadataProvider;
private readonly ICompositeModelBinder _compositeModelBinder;
private readonly IValueProviderFactory _compositeValueProviderFactory;
- private readonly IInputFormatterProvider _inputFormatterProvider;
+ private readonly IInputFormatterSelector _inputFormatterSelector;
private readonly IEnumerable _validatorProviders;
private Tuple _bindingContext;
public DefaultActionBindingContextProvider(IModelMetadataProvider modelMetadataProvider,
ICompositeModelBinder compositeModelBinder,
ICompositeValueProviderFactory compositeValueProviderFactory,
- IInputFormatterProvider inputFormatterProvider,
+ IInputFormatterSelector inputFormatterProvider,
IEnumerable validatorProviders)
{
_modelMetadataProvider = modelMetadataProvider;
_compositeModelBinder = compositeModelBinder;
_compositeValueProviderFactory = compositeValueProviderFactory;
- _inputFormatterProvider = inputFormatterProvider;
+ _inputFormatterSelector = inputFormatterProvider;
_validatorProviders = validatorProviders;
}
@@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Mvc
_modelMetadataProvider,
_compositeModelBinder,
valueProvider,
- _inputFormatterProvider,
+ _inputFormatterSelector,
_validatorProviders);
_bindingContext = new Tuple(actionContext, context);
diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs
index d1840e7958..53ace2f2e3 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs
@@ -2,6 +2,9 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.Framework.DependencyInjection;
@@ -12,16 +15,19 @@ namespace Microsoft.AspNet.Mvc
{
private readonly ReflectedActionDescriptor _descriptor;
private readonly IControllerFactory _controllerFactory;
+ private readonly IInputFormattersProvider _inputFormattersProvider;
+
public ReflectedActionInvoker([NotNull] ActionContext actionContext,
[NotNull] IActionBindingContextProvider bindingContextProvider,
[NotNull] INestedProviderManager filterProvider,
[NotNull] IControllerFactory controllerFactory,
- [NotNull] ReflectedActionDescriptor descriptor)
+ [NotNull] ReflectedActionDescriptor descriptor,
+ [NotNull] IInputFormattersProvider inputFormattersProvider)
: base(actionContext, bindingContextProvider, filterProvider)
{
_descriptor = descriptor;
_controllerFactory = controllerFactory;
-
+ _inputFormattersProvider = inputFormattersProvider;
if (descriptor.MethodInfo == null)
{
throw new ArgumentException(
@@ -34,9 +40,11 @@ namespace Microsoft.AspNet.Mvc
public override Task InvokeAsync()
{
ActionContext.Controller = _controllerFactory.CreateController(ActionContext);
+ ActionContext.InputFormatters = _inputFormattersProvider.InputFormatters
+ .ToList();
return base.InvokeAsync();
}
-
+
protected override async Task InvokeActionAsync(ActionExecutingContext actionExecutingContext)
{
var actionMethodInfo = _descriptor.MethodInfo;
@@ -81,4 +89,4 @@ namespace Microsoft.AspNet.Mvc
};
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvokerProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvokerProvider.cs
index 596c071335..242a4014be 100644
--- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvokerProvider.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvokerProvider.cs
@@ -10,14 +10,17 @@ namespace Microsoft.AspNet.Mvc
{
private readonly IControllerFactory _controllerFactory;
private readonly IActionBindingContextProvider _bindingProvider;
+ private readonly IInputFormattersProvider _inputFormattersProvider;
private readonly INestedProviderManager _filterProvider;
public ReflectedActionInvokerProvider(IControllerFactory controllerFactory,
IActionBindingContextProvider bindingProvider,
+ IInputFormattersProvider inputFormattersProvider,
INestedProviderManager filterProvider)
{
_controllerFactory = controllerFactory;
_bindingProvider = bindingProvider;
+ _inputFormattersProvider = inputFormattersProvider;
_filterProvider = filterProvider;
}
@@ -37,7 +40,8 @@ namespace Microsoft.AspNet.Mvc
_bindingProvider,
_filterProvider,
_controllerFactory,
- actionDescriptor);
+ actionDescriptor,
+ _inputFormattersProvider);
}
callNext();
diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs
index e81c316a82..e5d4e993cf 100644
--- a/src/Microsoft.AspNet.Mvc/MvcServices.cs
+++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs
@@ -64,8 +64,8 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Transient();
yield return describe.Scoped();
- yield return describe.Transient();
- yield return describe.Transient();
+ yield return describe.Transient();
+ yield return describe.Scoped();
yield return describe.Transient();
yield return describe.Scoped();
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs
index bd39dfead3..960445641a 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs
@@ -577,7 +577,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
binder.Object,
valueProvider,
- Mock.Of(),
+ Mock.Of(),
Enumerable.Empty());
var bindingContextProvider = new Mock();
bindingContextProvider.Setup(b => b.GetActionBindingContextAsync(actionContext))
@@ -618,7 +618,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
binder.Object,
valueProvider,
- Mock.Of(),
+ Mock.Of(),
Enumerable.Empty());
var bindingContextProvider = new Mock();
bindingContextProvider.Setup(b => b.GetActionBindingContextAsync(actionContext))
@@ -659,7 +659,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
binder.Object,
Mock.Of(),
- Mock.Of(),
+ Mock.Of(),
Enumerable.Empty());
var bindingContextProvider = new Mock();
bindingContextProvider.Setup(b => b.GetActionBindingContextAsync(actionContext))
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultInputFormatterSelectorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultInputFormatterSelectorTests.cs
new file mode 100644
index 0000000000..38e58181a5
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultInputFormatterSelectorTests.cs
@@ -0,0 +1,70 @@
+// Copyright (c) Microsoft Open Technologies, Inc. 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.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Http;
+using Microsoft.AspNet.Routing;
+using Microsoft.Framework.DependencyInjection;
+using Moq;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.Core.Test
+{
+ public class DefaultInputFormatterSelectorTests
+ {
+ [Fact]
+ public void DefaultInputFormatterSelectorTests_ReturnsFirstFormatterWhichReturnsTrue()
+ {
+ // Arrange
+ var actionContext = GetActionContext();
+ var context = new InputFormatterContext(actionContext, typeof(int));
+ actionContext.InputFormatters = new List()
+ {
+ new TestInputFormatter(false, 0),
+ new TestInputFormatter(false, 1),
+ new TestInputFormatter(true, 2),
+ new TestInputFormatter(true, 3)
+ };
+
+ var selector = new DefaultInputFormatterSelector();
+
+ // Act
+ var selectedFormatter = selector.SelectFormatter(context);
+
+ // Assert
+ var testFormatter = Assert.IsType(selectedFormatter);
+ Assert.Equal(2, testFormatter.Index);
+ }
+
+ private static ActionContext GetActionContext()
+ {
+ var httpContext = Mock.Of();
+ return new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
+
+ }
+
+ private class TestInputFormatter : IInputFormatter
+ {
+ private bool _canRead = false;
+
+ public TestInputFormatter(bool canRead, int index)
+ {
+ _canRead = canRead;
+ Index = index;
+ }
+ public int Index { get; set; }
+
+ public bool CanRead(InputFormatterContext context)
+ {
+ return _canRead;
+ }
+
+ public Task