Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Adding JsonInputFormatter for reading json encoded data from the request body #87

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ public ActionBindingContext(ActionContext context,
IModelMetadataProvider metadataProvider,
IModelBinder modelBinder,
IValueProvider valueProvider,
IInputFormatter inputFormatter,
IInputFormatterProvider inputFormatterProvider,
IEnumerable<IModelValidatorProvider> validatorProviders)
{
ActionContext = context;
MetadataProvider = metadataProvider;
ModelBinder = modelBinder;
ValueProvider = valueProvider;
InputFormatter = inputFormatter;
InputFormatterProvider = inputFormatterProvider;
ValidatorProviders = validatorProviders;
}

Expand All @@ -28,7 +28,7 @@ public ActionBindingContext(ActionContext context,

public IValueProvider ValueProvider { get; private set; }

public IInputFormatter InputFormatter { get; private set; }
public IInputFormatterProvider InputFormatterProvider { get; private set; }

public IEnumerable<IModelValidatorProvider> ValidatorProviders { get; private set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ public class DefaultActionBindingContextProvider : IActionBindingContextProvider
private readonly IModelMetadataProvider _modelMetadataProvider;
private readonly IEnumerable<IModelBinder> _modelBinders;
private readonly IEnumerable<IValueProviderFactory> _valueProviderFactories;
private readonly IEnumerable<IInputFormatter> _inputFormatters;
private readonly IInputFormatterProvider _inputFormatterProvider;
private readonly IEnumerable<IModelValidatorProvider> _validatorProviders;

public DefaultActionBindingContextProvider(IModelMetadataProvider modelMetadataProvider,
IEnumerable<IModelBinder> modelBinders,
IEnumerable<IValueProviderFactory> valueProviderFactories,
IEnumerable<IInputFormatter> inputFormatters,
IInputFormatterProvider inputFormatterProvider,
IEnumerable<IModelValidatorProvider> validatorProviders)
{
_modelMetadataProvider = modelMetadataProvider;
_modelBinders = modelBinders.OrderBy(binder => binder.GetType() == typeof(ComplexModelDtoModelBinder) ? 1 : 0);
_valueProviderFactories = valueProviderFactories;
_inputFormatters = inputFormatters;
_inputFormatterProvider = inputFormatterProvider;
_validatorProviders = validatorProviders;
}

Expand All @@ -38,7 +38,7 @@ public async Task<ActionBindingContext> GetActionBindingContextAsync(ActionConte
_modelMetadataProvider,
new CompositeModelBinder(_modelBinders),
new CompositeValueProvider(valueProviders),
new CompositeInputFormatter(_inputFormatters),
_inputFormatterProvider,
_validatorProviders
);
}
Expand Down
43 changes: 32 additions & 11 deletions src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Threading.Tasks;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Mvc.Filters;
using Microsoft.AspNet.Mvc.Internal;
using Microsoft.AspNet.Mvc.ModelBinding;

namespace Microsoft.AspNet.Mvc
Expand Down Expand Up @@ -132,24 +131,46 @@ private async Task<IDictionary<string, object>> GetParameterValues(ModelStateDic
{
var actionBindingContext = await _bindingProvider.GetActionBindingContextAsync(_actionContext);
var parameters = _descriptor.Parameters;

var metadataProvider = actionBindingContext.MetadataProvider;
var parameterValues = new Dictionary<string, object>(parameters.Count, StringComparer.Ordinal);
for (int i = 0; i < parameters.Count; i++)

for (var i = 0; i < parameters.Count; i++)
{
var parameter = parameters[i];
if (parameter.BodyParameterInfo != null)
{
var inputFormatterContext = actionBindingContext.CreateInputFormatterContext(
modelState,
parameter);
await actionBindingContext.InputFormatter.ReadAsync(inputFormatterContext);
parameterValues[parameter.Name] = inputFormatterContext.Model;
var parameterType = parameter.BodyParameterInfo.ParameterType;
var modelMetadata = metadataProvider.GetMetadataForType(modelAccessor: null, modelType: parameterType);
var providerContext = new InputFormatterProviderContext(actionBindingContext.ActionContext.HttpContext,
modelMetadata,
modelState);

var inputFormatter = actionBindingContext.InputFormatterProvider.GetInputFormatter(providerContext);


var formatterContext = new InputFormatterContext(actionBindingContext.ActionContext.HttpContext,
modelMetadata,
modelState);
await inputFormatter.ReadAsync(formatterContext);
parameterValues[parameter.Name] = formatterContext.Model;
}
else
{
var modelBindingContext = actionBindingContext.CreateModelBindingContext(
modelState,
parameter);
var parameterType = parameter.ParameterBindingInfo.ParameterType;
var modelMetadata = metadataProvider.GetMetadataForType(modelAccessor: null, modelType: parameterType);

var modelBindingContext = new ModelBindingContext
{
ModelName = parameter.Name,
ModelState = modelState,
ModelMetadata = modelMetadata,
ModelBinder = actionBindingContext.ModelBinder,
ValueProvider = actionBindingContext.ValueProvider,
ValidatorProviders = actionBindingContext.ValidatorProviders,
MetadataProvider = metadataProvider,
HttpContext = actionBindingContext.ActionContext.HttpContext,
FallbackToEmptyPrefix = true
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is this change related to the PR's title?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a comment in the earlier iteration to remove the static helper that this was sitting in.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

actionBindingContext.ModelBinder.BindModel(modelBindingContext);
parameterValues[parameter.Name] = modelBindingContext.Model;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.AspNet.Mvc.ModelBinding
{
public interface IInputFormatter
{
Task<bool> ReadAsync(InputFormatterContext context);
/// <summary>
/// Gets the mutable collection of media types supported by this <see cref="JsonInputFormatter"/> instance.
/// </summary>
IList<string> SupportedMediaTypes { get; }

/// <summary>
/// Gets the mutable collection of character encodings supported by this <see cref="JsonInputFormatter"/>
/// instance.
/// </summary>
IList<Encoding> SupportedEncodings { get; }

/// <summary>
/// Called during deserialization to read an object from the request.
/// </summary>
Task ReadAsync(InputFormatterContext context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.AspNet.Mvc.ModelBinding
{
public interface IInputFormatterProvider
{
IInputFormatter GetInputFormatter(InputFormatterProviderContext context);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
using System;
using System.Text;
using Microsoft.AspNet.Abstractions;

namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class InputFormatterContext
{
public InputFormatterContext(ModelMetadata metadata, ModelStateDictionary modelState)
public InputFormatterContext([NotNull] HttpContext httpContext,
[NotNull] ModelMetadata metadata,
[NotNull] ModelStateDictionary modelState)
{
HttpContext = httpContext;
Metadata = metadata;
ModelState = modelState;
}

public HttpContext HttpContext { get; private set; }

public Encoding ContentEncoding { get; private set; }

public ModelMetadata Metadata { get; private set; }

public ModelStateDictionary ModelState { get; private set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNet.Abstractions;

namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class InputFormatterProviderContext
{
public InputFormatterProviderContext([NotNull] HttpContext httpContext,
[NotNull] ModelMetadata metadata,
[NotNull] ModelStateDictionary modelState)
{
HttpContext = httpContext;
Metadata = metadata;
ModelState = modelState;
}

public HttpContext HttpContext { get; private set; }

public ModelMetadata Metadata { get; private set; }

public ModelStateDictionary ModelState { get; private set; }
}
}
Loading