From 6f0fa671704cd1042e347355680a45ebdcf4ead0 Mon Sep 17 00:00:00 2001 From: harshgMSFT Date: Wed, 13 Aug 2014 13:56:51 -0700 Subject: [PATCH] Enabling basic input formatter selection. Conflicts: Mvc.sln src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvokerProvider.cs src/Microsoft.AspNet.Mvc/MvcServices.cs test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionInvokerTest.cs Conflicts: src/Microsoft.AspNet.Mvc.Core/Formatters/TempInputFormatterProvider.cs --- .../ActionContext.cs | 7 ++ .../FilterActionInvoker.cs | 10 +-- ...er.cs => DefaultInputFormatterSelector.cs} | 22 ++---- ...Provider.cs => IInputFormatterSelector.cs} | 4 +- .../InputFormatterProviderContext.cs | 26 ------- src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs | 2 +- .../ParameterBinding/ActionBindingContext.cs | 6 +- .../DefaultActionBindingContextProvider.cs | 8 +-- .../ReflectedActionInvoker.cs | 16 +++-- .../ReflectedActionInvokerProvider.cs | 6 +- src/Microsoft.AspNet.Mvc/MvcServices.cs | 4 +- .../ControllerTests.cs | 6 +- .../DefaultInputFormatterSelectorTests.cs | 70 +++++++++++++++++++ .../ReflectedActionInvokerTest.cs | 34 ++++++--- .../Rendering/DefaultTemplatesUtilities.cs | 2 +- 15 files changed, 141 insertions(+), 82 deletions(-) rename src/Microsoft.AspNet.Mvc.Core/Formatters/{TempInputFormatterProvider.cs => DefaultInputFormatterSelector.cs} (54%) rename src/Microsoft.AspNet.Mvc.Core/Formatters/{IInputFormatterProvider.cs => IInputFormatterSelector.cs} (73%) delete mode 100644 src/Microsoft.AspNet.Mvc.Core/Formatters/InputFormatterProviderContext.cs create mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/DefaultInputFormatterSelectorTests.cs 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 ReadAsync(InputFormatterContext context) + { + return Task.FromResult(Index); + } + } + } +} diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionInvokerTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionInvokerTest.cs index 441a8ff422..dde7523440 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionInvokerTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionInvokerTest.cs @@ -1329,13 +1329,16 @@ namespace Microsoft.AspNet.Mvc .Setup(fp => fp.Invoke(It.IsAny())) .Callback( context => context.Results.AddRange(filters.Select(f => new FilterItem(null, f)))); - + var inputFormattersProvider = new Mock(); + inputFormattersProvider.SetupGet(o => o.InputFormatters) + .Returns(new List()); var invoker = new ReflectedActionInvoker( actionContext, actionBindingContextProvider.Object, filterProvider.Object, controllerFactory.Object, - actionDescriptor); + actionDescriptor, + inputFormattersProvider.Object); return invoker; } @@ -1366,18 +1369,21 @@ namespace Microsoft.AspNet.Mvc Mock.Of(), binder.Object, Mock.Of(), - Mock.Of(), + Mock.Of(), Enumerable.Empty()); var actionBindingContextProvider = new Mock(); actionBindingContextProvider.Setup(p => p.GetActionBindingContextAsync(It.IsAny())) .Returns(Task.FromResult(bindingContext)); - + var inputFormattersProvider = new Mock(); + inputFormattersProvider.SetupGet(o => o.InputFormatters) + .Returns(new List()); var invoker = new ReflectedActionInvoker(actionContext, actionBindingContextProvider.Object, Mock.Of>(), Mock.Of(), - actionDescriptor); + actionDescriptor, + inputFormattersProvider.Object); var modelStateDictionary = new ModelStateDictionary(); @@ -1422,18 +1428,21 @@ namespace Microsoft.AspNet.Mvc Mock.Of(), binder.Object, Mock.Of(), - Mock.Of(), + Mock.Of(), Enumerable.Empty()); var actionBindingContextProvider = new Mock(); actionBindingContextProvider.Setup(p => p.GetActionBindingContextAsync(It.IsAny())) .Returns(Task.FromResult(bindingContext)); - + var inputFormattersProvider = new Mock(); + inputFormattersProvider.SetupGet(o => o.InputFormatters) + .Returns(new List()); var invoker = new ReflectedActionInvoker(actionContext, actionBindingContextProvider.Object, Mock.Of>(), Mock.Of(), - actionDescriptor); + actionDescriptor, + inputFormattersProvider.Object); var modelStateDictionary = new ModelStateDictionary(); @@ -1479,7 +1488,7 @@ namespace Microsoft.AspNet.Mvc Mock.Of(), binder.Object, Mock.Of(), - Mock.Of(), + Mock.Of(), Enumerable.Empty()); var actionBindingContextProvider = new Mock(); @@ -1488,12 +1497,15 @@ namespace Microsoft.AspNet.Mvc var controllerFactory = new Mock(); controllerFactory.Setup(c => c.CreateController(It.IsAny())) .Returns(new TestController()); - + var inputFormattersProvider = new Mock(); + inputFormattersProvider.SetupGet(o => o.InputFormatters) + .Returns(new List()); var invoker = new ReflectedActionInvoker(actionContext, actionBindingContextProvider.Object, Mock.Of>(), controllerFactory.Object, - actionDescriptor); + actionDescriptor, + inputFormattersProvider.Object); // Act await invoker.InvokeAsync(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs index a787cc760a..937ff4d7a0 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs @@ -92,7 +92,7 @@ namespace Microsoft.AspNet.Mvc.Core provider, Mock.Of(), Mock.Of(), - Mock.Of(), + Mock.Of(), Enumerable.Empty()); var urlHelper = Mock.Of(); var actionBindingContextProvider = new Mock();