public async Task<IDictionary<string, object>> BindArgumentsAsync(WidgetContext context, MethodInfo method, IDictionary<string, object> values)
{
var bindingContext = new OperationBindingContext
{
HttpContext = context.ViewContext.HttpContext,
InputFormatters = _options.InputFormatters,
MetadataProvider = _modelMetadataProvider,
ModelBinder = new CompositeModelBinder(_options.ModelBinders),
ValidatorProvider = new CompositeModelValidatorProvider(_options.ModelValidatorProviders),
ValueProvider = await CompositeValueProvider.CreateAsync(_options.ValueProviderFactories, new ValueProviderFactoryContext(context.ViewContext.HttpContext, context.ViewContext.RouteData.Values))
};
var arguments = new Dictionary<string, object>(StringComparer.Ordinal);
var parameters = method.GetParameters();
foreach (var parameter in parameters)
{
if (values.ContainsKey(parameter.Name))
{
arguments.Add(parameter.Name, values[parameter.Name]);
}
else
{
var attribute = parameter.GetCustomAttributes().OfType<IBindingSourceMetadata>().FirstOrDefault();
var bindingInfo = new BindingInfo()
{
BindingSource = attribute?.BindingSource
};
var metadata = _modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
var modelBindingContext = ModelBindingContext.CreateBindingContext(
bindingContext,
context.ModelState,
metadata,
bindingInfo,
parameter.Name);
var result = await bindingContext.ModelBinder.BindModelAsync(modelBindingContext);
if (result.IsModelSet)
{
_objectModelValidator.Validate(bindingContext.ValidatorProvider, context.ModelState, modelBindingContext.ValidationState, result.Key, result.Model);
arguments.Add(parameter.Name, result.Model);
}
else
{
arguments.Add(parameter.Name, Activator.CreateInstance(parameter.ParameterType));
}
}
}
return arguments;
}
}