Fix for #1681 - Model state errors are wrong with attributes like [FromHeader]
The issue here is that a model state error is added with the model name 'doubled'. This is on a fairly obscure code path and the code dates back to the original WSR git checkin of webapi. There are no wsr tests that verify this behavior. The cause here is that our 'greedy' model binders (like FromHeaderModelBinder) return 'true' whether or not they successfully found a model, because they don't want other model binders to run. This also has an effect on the validation system. That means that validators will run and attempt to validate the model (which may be null). That's that rare case where we get to this code path.
This commit is contained in:
parent
b1b541404c
commit
1631ca1a47
|
|
@ -190,11 +190,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// If the Model at the current node is null and there is no parent, we cannot validate, and the
|
||||
// DataAnnotationsModelValidator will throw. So we intercept here to provide a catch-all value-required
|
||||
// validation error
|
||||
var modelStateKey = ModelBindingHelper.CreatePropertyModelName(ModelStateKey,
|
||||
ModelMetadata.GetDisplayName());
|
||||
if (parentNode == null && ModelMetadata.Model == null)
|
||||
{
|
||||
modelState.TryAddModelError(modelStateKey, Resources.Validation_ValueNotFound);
|
||||
modelState.TryAddModelError(ModelStateKey, Resources.Validation_ValueNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,10 +96,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
Assert.Null(result.HeaderValue);
|
||||
Assert.Null(result.HeaderValues);
|
||||
|
||||
// This is a bug - the model state error key is wrong here.
|
||||
|
||||
var error = Assert.Single(result.ModelStateErrors);
|
||||
Assert.Equal("transactionId.transactionId", error);
|
||||
Assert.Equal("transactionId", error);
|
||||
}
|
||||
|
||||
// The action that this test hits will echo back the model-bound values
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
#if ASPNET50
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
|
|
@ -245,6 +246,27 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
Assert.Empty(log);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_ValidatesIfModelIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var modelMetadata = GetModelMetadata(typeof(ValidateAllPropertiesModel));
|
||||
var node = new ModelValidationNode(modelMetadata, "theKey");
|
||||
|
||||
var context = CreateContext(modelMetadata);
|
||||
|
||||
// Act
|
||||
node.Validate(context);
|
||||
|
||||
// Assert
|
||||
var modelState = Assert.Single(context.ModelState);
|
||||
Assert.Equal("theKey", modelState.Key);
|
||||
Assert.Equal(ModelValidationState.Invalid, modelState.Value.ValidationState);
|
||||
|
||||
var error = Assert.Single(modelState.Value.Errors);
|
||||
Assert.Equal("A value is required but was not present in the request.", error.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[ReplaceCulture]
|
||||
public void Validate_ValidateAllProperties_AddsValidationErrors()
|
||||
|
|
@ -321,6 +343,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return new DataAnnotationsModelMetadataProvider().GetMetadataForType(() => o, o.GetType());
|
||||
}
|
||||
|
||||
private static ModelMetadata GetModelMetadata(Type type)
|
||||
{
|
||||
return new DataAnnotationsModelMetadataProvider().GetMetadataForType(modelAccessor: null, modelType: type);
|
||||
}
|
||||
|
||||
private static ModelValidationContext CreateContext(ModelMetadata metadata = null)
|
||||
{
|
||||
var providers = new IModelValidatorProvider[]
|
||||
|
|
|
|||
Loading…
Reference in New Issue