Pass InputFormatters in OBC

This removes the need to use IScopedInstance<ActionBindingContext> to get
access to the formatters.
This commit is contained in:
Ryan Nowak 2015-05-13 15:11:17 -07:00
parent 4b1a708ba1
commit 90805fa827
10 changed files with 62 additions and 33 deletions

View File

@ -1,6 +1,7 @@
// 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.Collections.Generic;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
@ -22,6 +23,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
/// </summary>
public HttpContext HttpContext { get; set; }
/// <summary>
/// Gets or sets the set of <see cref="IInputFormatter"/> instances associated with this context.
/// </summary>
public IList<IInputFormatter> InputFormatters { get; set; }
/// <summary>
/// Gets unaltered value provider collection.
/// Value providers can be filtered by specific model binders.

View File

@ -1050,6 +1050,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider);
}
@ -1088,6 +1089,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
BindingContext.ValueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
includeExpressions);
@ -1126,6 +1128,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
BindingContext.ValueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
predicate);
@ -1167,6 +1170,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
includeExpressions);
@ -1207,6 +1211,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
predicate);
@ -1243,6 +1248,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
BindingContext.ValueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider);
}
@ -1283,6 +1289,7 @@ namespace Microsoft.AspNet.Mvc
MetadataProvider,
BindingContext.ModelBinder,
valueProvider,
BindingContext.InputFormatters,
ObjectValidator,
BindingContext.ValidatorProvider,
predicate);

View File

@ -209,6 +209,7 @@ namespace Microsoft.AspNet.Mvc
{
return new OperationBindingContext
{
InputFormatters = bindingContext.InputFormatters,
ModelBinder = bindingContext.ModelBinder,
ValidatorProvider = bindingContext.ValidatorProvider,
MetadataProvider = _modelMetadataProvider,

View File

@ -28,11 +28,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
protected async override Task<ModelBindingResult> BindModelCoreAsync(
[NotNull] ModelBindingContext bindingContext)
{
var requestServices = bindingContext.OperationBindingContext.HttpContext.RequestServices;
var httpContext = bindingContext.OperationBindingContext.HttpContext;
var formatters = requestServices
.GetRequiredService<IScopedInstance<ActionBindingContext>>().Value.InputFormatters;
var formatters = bindingContext.OperationBindingContext.InputFormatters;
var formatterContext = new InputFormatterContext(
httpContext,

View File

@ -35,6 +35,9 @@ namespace Microsoft.AspNet.Mvc
/// <param name="metadataProvider">The provider used for reading metadata for the model type.</param>
/// <param name="modelBinder">The <see cref="IModelBinder"/> used for binding.</param>
/// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param>
/// <param name="inputFormatters">
/// The set of <see cref="IInputFormatter"/> instances for deserializing the body.
/// </param>
/// <param name="objectModelValidator">The <see cref="IObjectModelValidator"/> used for validating the
/// bound values.</param>
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/> used for executing validation
@ -48,6 +51,7 @@ namespace Microsoft.AspNet.Mvc
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IModelBinder modelBinder,
[NotNull] IValueProvider valueProvider,
[NotNull] IList<IInputFormatter> inputFormatters,
[NotNull] IObjectModelValidator objectModelValidator,
[NotNull] IModelValidatorProvider validatorProvider)
where TModel : class
@ -61,6 +65,7 @@ namespace Microsoft.AspNet.Mvc
metadataProvider,
modelBinder,
valueProvider,
inputFormatters,
objectModelValidator,
validatorProvider,
predicate: (context, propertyName) => true);
@ -81,6 +86,9 @@ namespace Microsoft.AspNet.Mvc
/// <param name="metadataProvider">The provider used for reading metadata for the model type.</param>
/// <param name="modelBinder">The <see cref="IModelBinder"/> used for binding.</param>
/// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param>
/// <param name="inputFormatters">
/// The set of <see cref="IInputFormatter"/> instances for deserializing the body.
/// </param>
/// <param name="objectModelValidator">The <see cref="IObjectModelValidator"/> used for validating the
/// bound values.</param>
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/> used for executing validation
@ -97,6 +105,7 @@ namespace Microsoft.AspNet.Mvc
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IModelBinder modelBinder,
[NotNull] IValueProvider valueProvider,
[NotNull] IList<IInputFormatter> inputFormatters,
[NotNull] IObjectModelValidator objectModelValidator,
[NotNull] IModelValidatorProvider validatorProvider,
[NotNull] params Expression<Func<TModel, object>>[] includeExpressions)
@ -113,6 +122,7 @@ namespace Microsoft.AspNet.Mvc
metadataProvider,
modelBinder,
valueProvider,
inputFormatters,
objectModelValidator,
validatorProvider,
predicate: predicate);
@ -133,6 +143,9 @@ namespace Microsoft.AspNet.Mvc
/// <param name="metadataProvider">The provider used for reading metadata for the model type.</param>
/// <param name="modelBinder">The <see cref="IModelBinder"/> used for binding.</param>
/// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param>
/// <param name="inputFormatters">
/// The set of <see cref="IInputFormatter"/> instances for deserializing the body.
/// </param>
/// <param name="objectModelValidator">The <see cref="IObjectModelValidator"/> used for validating the
/// bound values.</param>
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/> used for executing validation
@ -148,6 +161,7 @@ namespace Microsoft.AspNet.Mvc
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IModelBinder modelBinder,
[NotNull] IValueProvider valueProvider,
[NotNull] IList<IInputFormatter> inputFormatters,
[NotNull] IObjectModelValidator objectModelValidator,
[NotNull] IModelValidatorProvider validatorProvider,
[NotNull] Func<ModelBindingContext, string, bool> predicate)
@ -162,6 +176,7 @@ namespace Microsoft.AspNet.Mvc
metadataProvider,
modelBinder,
valueProvider,
inputFormatters,
objectModelValidator,
validatorProvider,
predicate: predicate);
@ -182,6 +197,9 @@ namespace Microsoft.AspNet.Mvc
/// <param name="metadataProvider">The provider used for reading metadata for the model type.</param>
/// <param name="modelBinder">The <see cref="IModelBinder"/> used for binding.</param>
/// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param>
/// <param name="inputFormatters">
/// The set of <see cref="IInputFormatter"/> instances for deserializing the body.
/// </param>
/// <param name="objectModelValidator">The <see cref="IObjectModelValidator"/> used for validating the
/// bound values.</param>
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/> used for executing validation
@ -196,6 +214,7 @@ namespace Microsoft.AspNet.Mvc
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IModelBinder modelBinder,
[NotNull] IValueProvider valueProvider,
[NotNull] IList<IInputFormatter> inputFormatters,
[NotNull] IObjectModelValidator objectModelValidator,
[NotNull] IModelValidatorProvider validatorProvider)
{
@ -209,6 +228,7 @@ namespace Microsoft.AspNet.Mvc
metadataProvider,
modelBinder,
valueProvider,
inputFormatters,
objectModelValidator,
validatorProvider,
predicate: (context, propertyName) => true);
@ -229,6 +249,9 @@ namespace Microsoft.AspNet.Mvc
/// <param name="metadataProvider">The provider used for reading metadata for the model type.</param>
/// <param name="modelBinder">The <see cref="IModelBinder"/> used for binding.</param>
/// <param name="valueProvider">The <see cref="IValueProvider"/> used for looking up values.</param>
/// <param name="inputFormatters">
/// The set of <see cref="IInputFormatter"/> instances for deserializing the body.
/// </param>
/// <param name="objectModelValidator">The <see cref="IObjectModelValidator"/> used for validating the
/// bound values.</param>
/// <param name="validatorProvider">The <see cref="IModelValidatorProvider"/> used for executing validation
@ -245,6 +268,7 @@ namespace Microsoft.AspNet.Mvc
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IModelBinder modelBinder,
[NotNull] IValueProvider valueProvider,
[NotNull] IList<IInputFormatter> inputFormatters,
[NotNull] IObjectModelValidator objectModelValidator,
[NotNull] IModelValidatorProvider validatorProvider,
[NotNull] Func<ModelBindingContext, string, bool> predicate)
@ -264,6 +288,7 @@ namespace Microsoft.AspNet.Mvc
var operationBindingContext = new OperationBindingContext
{
InputFormatters = inputFormatters,
ModelBinder = modelBinder,
ValidatorProvider = validatorProvider,
MetadataProvider = metadataProvider,

View File

@ -234,7 +234,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
httpContext = new DefaultHttpContext();
}
UpdateServiceProvider(httpContext, inputFormatters ?? Enumerable.Empty<IInputFormatter>());
if (inputFormatters == null)
{
inputFormatters = Enumerable.Empty<IInputFormatter>();
}
if (metadataProvider == null)
{
@ -243,6 +246,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var operationBindingContext = new OperationBindingContext
{
InputFormatters = inputFormatters.ToList(),
ModelBinder = new BodyModelBinder(),
MetadataProvider = metadataProvider,
HttpContext = httpContext,
@ -261,26 +265,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return bindingContext;
}
private static void UpdateServiceProvider(
HttpContext httpContext,
IEnumerable<IInputFormatter> inputFormatters)
{
var serviceProvider = new ServiceCollection();
var bindingContext = new ActionBindingContext()
{
InputFormatters = inputFormatters.ToArray(),
};
var bindingContextAccessor = new MockScopedInstance<ActionBindingContext>()
{
Value = bindingContext,
};
serviceProvider.AddInstance<IScopedInstance<ActionBindingContext>>(bindingContextAccessor);
serviceProvider.AddInstance(CreateActionContext(httpContext));
httpContext.RequestServices = serviceProvider.BuildServiceProvider();
}
private static IScopedInstance<ActionContext> CreateActionContext(HttpContext context)
{
return CreateActionContext(context, (new Mock<IRouter>()).Object);

View File

@ -38,6 +38,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binder.Object),
Mock.Of<IValueProvider>(),
new List<IInputFormatter>(),
new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider),
Mock.Of<IModelValidatorProvider>());
@ -78,6 +79,7 @@ namespace Microsoft.AspNet.Mvc.Test
modelMetadataProvider,
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], modelMetadataProvider),
validator);
@ -118,6 +120,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider),
validator);
@ -147,6 +150,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binder.Object),
Mock.Of<IValueProvider>(),
new List<IInputFormatter>(),
Mock.Of<IObjectModelValidator>(),
Mock.Of<IModelValidatorProvider>(),
includePredicate);
@ -202,6 +206,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider),
validator,
includePredicate);
@ -233,6 +238,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binder.Object),
Mock.Of<IValueProvider>(),
new List<IInputFormatter>(),
Mock.Of<IObjectModelValidator>(),
Mock.Of<IModelValidatorProvider>(),
m => m.IncludedProperty );
@ -284,6 +290,7 @@ namespace Microsoft.AspNet.Mvc.Test
TestModelMetadataProvider.CreateDefaultProvider(),
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider),
validator,
m => m.IncludedProperty,
@ -336,6 +343,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(new IExcludeTypeValidationFilter[0], metadataProvider),
validator);
@ -487,6 +495,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider: metadataProvider,
modelBinder: GetCompositeBinder(binder.Object),
valueProvider: Mock.Of<IValueProvider>(),
inputFormatters: new List<IInputFormatter>(),
objectModelValidator: Mock.Of<IObjectModelValidator>(),
validatorProvider: Mock.Of<IModelValidatorProvider>(),
predicate: includePredicate);
@ -544,6 +553,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(
new IExcludeTypeValidationFilter[0],
metadataProvider),
@ -578,6 +588,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider: metadataProvider,
modelBinder: GetCompositeBinder(binder.Object),
valueProvider: Mock.Of<IValueProvider>(),
inputFormatters: new List<IInputFormatter>(),
objectModelValidator: Mock.Of<IObjectModelValidator>(),
validatorProvider: Mock.Of<IModelValidatorProvider>());
@ -618,6 +629,7 @@ namespace Microsoft.AspNet.Mvc.Test
TestModelMetadataProvider.CreateDefaultProvider(),
GetCompositeBinder(binders),
valueProvider,
new List<IInputFormatter>(),
new DefaultObjectValidator(
new IExcludeTypeValidationFilter[0],
metadataProvider),
@ -652,6 +664,7 @@ namespace Microsoft.AspNet.Mvc.Test
metadataProvider,
GetCompositeBinder(binder.Object),
Mock.Of<IValueProvider>(),
new List<IInputFormatter>(),
new DefaultObjectValidator(
new IExcludeTypeValidationFilter[0],
metadataProvider),

View File

@ -49,11 +49,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
request.ContentType = "application/json";
});
var actionContext = operationContext
.HttpContext
.RequestServices
.GetRequiredService<IScopedInstance<ActionContext>>().Value;
var modelState = actionContext.ModelState;
var modelState = new ModelStateDictionary();
// Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext);
@ -140,9 +136,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
request.ContentType = "application/json";
});
var httpContext = operationContext.HttpContext;
var actionContext = httpContext.RequestServices.GetRequiredService<IScopedInstance<ActionContext>>().Value;
var modelState = actionContext.ModelState;
var modelState = new ModelStateDictionary();
// Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext);

View File

@ -41,6 +41,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
{
BodyBindingState = BodyBindingState.NotBodyBased,
HttpContext = httpContext,
InputFormatters = actionBindingContext.InputFormatters,
MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(),
ValidatorProvider = actionBindingContext.ValidatorProvider,
ValueProvider = actionBindingContext.ValueProvider,

View File

@ -576,6 +576,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
operationContext.MetadataProvider,
operationContext.ModelBinder,
operationContext.ValueProvider,
operationContext.InputFormatters,
ModelBindingTestHelper.GetObjectValidator(),
operationContext.ValidatorProvider);
}