Removing creating ModelValidationNode by default in CompositeModelBinder.
This moves the responsibility of of MVN creation to individual model binders if they want the individual models to be validated.
This commit is contained in:
parent
3fe0490b99
commit
4f419eee55
|
|
@ -89,12 +89,16 @@ namespace Microsoft.AspNet.Mvc
|
||||||
metadata,
|
metadata,
|
||||||
modelBindingResult.Model);
|
modelBindingResult.Model);
|
||||||
|
|
||||||
var validationContext = new ModelValidationContext(
|
if (modelBindingResult.ValidationNode != null)
|
||||||
modelBindingContext.BindingSource,
|
{
|
||||||
operationContext.ValidatorProvider,
|
var validationContext = new ModelValidationContext(
|
||||||
modelState,
|
modelBindingContext.BindingSource,
|
||||||
modelExplorer);
|
operationContext.ValidatorProvider,
|
||||||
_validator.Validate(validationContext, modelBindingResult.ValidationNode);
|
modelState,
|
||||||
|
modelExplorer);
|
||||||
|
|
||||||
|
_validator.Validate(validationContext, modelBindingResult.ValidationNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return modelBindingResult;
|
return modelBindingResult;
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var model = Convert.FromBase64String(value);
|
var model = Convert.FromBase64String(value);
|
||||||
|
var validationNode = new ModelValidationNode(
|
||||||
|
bindingContext.ModelName,
|
||||||
|
bindingContext.ModelMetadata,
|
||||||
|
model);
|
||||||
|
|
||||||
// We do not need to set an explict ModelValidationNode since CompositeModelBinder does that automatically.
|
|
||||||
return new ModelBindingResult(
|
return new ModelBindingResult(
|
||||||
model,
|
model,
|
||||||
bindingContext.ModelName,
|
bindingContext.ModelName,
|
||||||
isModelSet: true);
|
isModelSet: true,
|
||||||
|
validationNode: validationNode);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
if (bindingContext.ModelType == typeof(CancellationToken))
|
if (bindingContext.ModelType == typeof(CancellationToken))
|
||||||
{
|
{
|
||||||
var model = bindingContext.OperationBindingContext.HttpContext.RequestAborted;
|
var model = bindingContext.OperationBindingContext.HttpContext.RequestAborted;
|
||||||
return Task.FromResult(new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true));
|
var validationNode =
|
||||||
|
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, model);
|
||||||
|
return Task.FromResult(new ModelBindingResult(
|
||||||
|
model,
|
||||||
|
bindingContext.ModelName,
|
||||||
|
isModelSet: true,
|
||||||
|
validationNode: validationNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult<ModelBindingResult>(null);
|
return Task.FromResult<ModelBindingResult>(null);
|
||||||
|
|
|
||||||
|
|
@ -83,24 +83,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the model validation node if the model binding result was set but no validation node was provided.
|
|
||||||
// This would typically be the case where leaf level model binders, do not have to add a validation node
|
|
||||||
// for validation to take effect. The composite being the entry point for model binders, takes care or
|
|
||||||
// adding missing validation nodes.
|
|
||||||
var modelValidationNode = modelBindingResult.ValidationNode;
|
|
||||||
if (modelBindingResult.IsModelSet && modelValidationNode == null)
|
|
||||||
{
|
|
||||||
modelValidationNode = new ModelValidationNode(
|
|
||||||
bindingKey,
|
|
||||||
bindingContext.ModelMetadata,
|
|
||||||
modelBindingResult.Model);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ModelBindingResult(
|
return new ModelBindingResult(
|
||||||
modelBindingResult.Model,
|
modelBindingResult.Model,
|
||||||
bindingKey,
|
bindingKey,
|
||||||
modelBindingResult.IsModelSet,
|
modelBindingResult.IsModelSet,
|
||||||
modelValidationNode);
|
modelBindingResult.ValidationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ModelBindingResult> TryBind(ModelBindingContext bindingContext)
|
private async Task<ModelBindingResult> TryBind(ModelBindingContext bindingContext)
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
model = new FormCollection(new Dictionary<string, string[]>());
|
model = new FormCollection(new Dictionary<string, string[]>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true);
|
var validationNode =
|
||||||
|
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, model);
|
||||||
|
return new ModelBindingResult(
|
||||||
|
model,
|
||||||
|
bindingContext.ModelName,
|
||||||
|
isModelSet: true,
|
||||||
|
validationNode: validationNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,14 +24,26 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
var postedFiles = await GetFormFilesAsync(bindingContext);
|
var postedFiles = await GetFormFilesAsync(bindingContext);
|
||||||
var value = postedFiles.FirstOrDefault();
|
var value = postedFiles.FirstOrDefault();
|
||||||
return new ModelBindingResult(value, bindingContext.ModelName, isModelSet: value != null);
|
var validationNode =
|
||||||
|
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, value);
|
||||||
|
return new ModelBindingResult(
|
||||||
|
value,
|
||||||
|
bindingContext.ModelName,
|
||||||
|
isModelSet: value != null,
|
||||||
|
validationNode: validationNode);
|
||||||
}
|
}
|
||||||
else if (typeof(IEnumerable<IFormFile>).GetTypeInfo().IsAssignableFrom(
|
else if (typeof(IEnumerable<IFormFile>).GetTypeInfo().IsAssignableFrom(
|
||||||
bindingContext.ModelType.GetTypeInfo()))
|
bindingContext.ModelType.GetTypeInfo()))
|
||||||
{
|
{
|
||||||
var postedFiles = await GetFormFilesAsync(bindingContext);
|
var postedFiles = await GetFormFilesAsync(bindingContext);
|
||||||
var value = ModelBindingHelper.ConvertValuesToCollectionType(bindingContext.ModelType, postedFiles);
|
var value = ModelBindingHelper.ConvertValuesToCollectionType(bindingContext.ModelType, postedFiles);
|
||||||
return new ModelBindingResult(value, bindingContext.ModelName, isModelSet: value != null);
|
var validationNode =
|
||||||
|
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, value);
|
||||||
|
return new ModelBindingResult(
|
||||||
|
value,
|
||||||
|
bindingContext.ModelName,
|
||||||
|
isModelSet: value != null,
|
||||||
|
validationNode: validationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
newModel = valueProviderResult.ConvertTo(bindingContext.ModelType);
|
newModel = valueProviderResult.ConvertTo(bindingContext.ModelType);
|
||||||
ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel);
|
ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel);
|
||||||
|
var validationNode = new ModelValidationNode(
|
||||||
|
bindingContext.ModelName,
|
||||||
|
bindingContext.ModelMetadata,
|
||||||
|
newModel);
|
||||||
|
|
||||||
// We do not need to set an explict ModelValidationNode since CompositeModelBinder does that automatically.
|
|
||||||
return new ModelBindingResult(
|
return new ModelBindingResult(
|
||||||
newModel,
|
newModel,
|
||||||
bindingContext.ModelName,
|
bindingContext.ModelName,
|
||||||
isModelSet: true);
|
isModelSet: true,
|
||||||
|
validationNode: validationNode);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
|
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
|
||||||
var model = valueProviderResult.RawValue;
|
var model = valueProviderResult.RawValue;
|
||||||
ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model);
|
ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model);
|
||||||
|
var validationNode = new ModelValidationNode(
|
||||||
|
bindingContext.ModelName,
|
||||||
|
bindingContext.ModelMetadata,
|
||||||
|
model);
|
||||||
|
|
||||||
// We do not need to set an explict ModelValidationNode since CompositeModelBinder does that automatically.
|
|
||||||
return new ModelBindingResult(
|
return new ModelBindingResult(
|
||||||
model,
|
model,
|
||||||
bindingContext.ModelName,
|
bindingContext.ModelName,
|
||||||
isModelSet: true);
|
isModelSet: true,
|
||||||
|
validationNode: validationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<ValueProviderResult> GetCompatibleValueProviderResult(ModelBindingContext context)
|
internal static async Task<ValueProviderResult> GetCompatibleValueProviderResult(ModelBindingContext context)
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
if (mbc.ModelType == typeof(int))
|
if (mbc.ModelType == typeof(int))
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ModelBindingResult(42, mbc.ModelName, true));
|
var model = 42;
|
||||||
|
var validationNode = new ModelValidationNode(mbc.ModelName, mbc.ModelMetadata, model);
|
||||||
|
return Task.FromResult(new ModelBindingResult(model, mbc.ModelName, true, validationNode));
|
||||||
}
|
}
|
||||||
return Task.FromResult<ModelBindingResult>(null);
|
return Task.FromResult<ModelBindingResult>(null);
|
||||||
});
|
});
|
||||||
|
|
@ -325,7 +327,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
if (mbc.ModelType == typeof(string))
|
if (mbc.ModelType == typeof(string))
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ModelBindingResult("some-value", mbc.ModelName, true));
|
var model = "some-value";
|
||||||
|
var validationNode = new ModelValidationNode(mbc.ModelName, mbc.ModelMetadata, model);
|
||||||
|
return Task.FromResult(new ModelBindingResult(model, mbc.ModelName, true, validationNode));
|
||||||
}
|
}
|
||||||
return Task.FromResult<ModelBindingResult>(null);
|
return Task.FromResult<ModelBindingResult>(null);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -588,10 +588,14 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
private static ActionBindingContext GetActionBindingContext(object model)
|
private static ActionBindingContext GetActionBindingContext(object model)
|
||||||
{
|
{
|
||||||
var binder = new Mock<IModelBinder>();
|
var binder = new Mock<IModelBinder>();
|
||||||
binder
|
binder.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
.Returns<ModelBindingContext>(mbc =>
|
||||||
.Returns(Task.FromResult(
|
{
|
||||||
result: new ModelBindingResult(model: model, key: string.Empty, isModelSet: true)));
|
var validationNode = new ModelValidationNode(string.Empty, mbc.ModelMetadata, model);
|
||||||
|
return Task.FromResult(
|
||||||
|
result: new ModelBindingResult(model, string.Empty, isModelSet: true, validationNode: validationNode));
|
||||||
|
});
|
||||||
|
|
||||||
return new ActionBindingContext()
|
return new ActionBindingContext()
|
||||||
{
|
{
|
||||||
ModelBinder = binder.Object,
|
ModelBinder = binder.Object,
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,9 @@ namespace ModelBindingWebSite.Controllers
|
||||||
// by the type converter binder.
|
// by the type converter binder.
|
||||||
OrderStatus model;
|
OrderStatus model;
|
||||||
var isModelSet = Enum.TryParse<OrderStatus>("Status" + request.Query.Get("status"), out model);
|
var isModelSet = Enum.TryParse<OrderStatus>("Status" + request.Query.Get("status"), out model);
|
||||||
return Task.FromResult(new ModelBindingResult(model, "status", isModelSet));
|
var validationNode =
|
||||||
|
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, model);
|
||||||
|
return Task.FromResult(new ModelBindingResult(model, "status", isModelSet, validationNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult<ModelBindingResult>(null);
|
return Task.FromResult<ModelBindingResult>(null);
|
||||||
|
|
@ -99,7 +101,9 @@ namespace ModelBindingWebSite.Controllers
|
||||||
var value = await bindingContext.ValueProvider.GetValueAsync(key);
|
var value = await bindingContext.ValueProvider.GetValueAsync(key);
|
||||||
model.ProductId = (int)value.ConvertTo(typeof(int));
|
model.ProductId = (int)value.ConvertTo(typeof(int));
|
||||||
|
|
||||||
return new ModelBindingResult(model, key, true);
|
var validationNode =
|
||||||
|
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, value);
|
||||||
|
return new ModelBindingResult(model, key, true, validationNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue