diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj b/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj
index f7812e207f..9b287b48e1 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Microsoft.AspNet.Mvc.ModelBinding.kproj
@@ -66,6 +66,7 @@
+
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelState.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelState.cs
index 3209b172b0..ec09a275b2 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelState.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelState.cs
@@ -28,6 +28,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
get { return _errors; }
}
- public bool? IsValid { get; set; }
+ public ModelValidationState ValidationState { get; set; }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelStateDictionary.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelStateDictionary.cs
index 296e6e6c01..5a806f23d8 100644
--- a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelStateDictionary.cs
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelStateDictionary.cs
@@ -61,9 +61,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
}
#endregion
- public bool? IsValid
+ public bool IsValid
{
- get { return GetValidity(_innerDictionary); }
+ get { return ValidationState == ModelValidationState.Valid; }
+ }
+
+ public ModelValidationState ValidationState
+ {
+ get { return GetValidity(_innerDictionary); }
}
public ModelState this[[NotNull] string key]
@@ -87,14 +92,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void AddModelError([NotNull] string key, [NotNull] Exception exception)
{
var modelState = GetModelStateForKey(key);
- modelState.IsValid = false;
+ modelState.ValidationState = ModelValidationState.Invalid;
modelState.Errors.Add(exception);
}
public void AddModelError([NotNull] string key, [NotNull] string errorMessage)
{
var modelState = GetModelStateForKey(key);
- modelState.IsValid = false;
+ modelState.ValidationState = ModelValidationState.Invalid;
modelState.Errors.Add(errorMessage);
}
@@ -106,19 +111,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return null;
}
- return GetValidity(entries);
+ var validity = GetValidity(entries);
+ if (validity == ModelValidationState.Unvalidated)
+ {
+ return null;
+ }
+
+ return validity == ModelValidationState.Valid;
}
public void MarkFieldValid([NotNull] string key)
{
var modelState = GetModelStateForKey(key);
- if (modelState.IsValid == false)
+ if (modelState.ValidationState == ModelValidationState.Invalid)
{
- // TODO We should never end up here from our code
throw new InvalidOperationException(Resources.Validation_InvalidFieldCannotBeReset);
}
- modelState.IsValid = true;
+ modelState.ValidationState = ModelValidationState.Valid;
}
public void Merge(ModelStateDictionary dictionary)
@@ -151,23 +161,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return modelState;
}
- private static bool? GetValidity(IEnumerable> entries)
+ private static ModelValidationState GetValidity(IEnumerable> entries)
{
- var state = true;
+ var validationState = ModelValidationState.Valid;
foreach (var entry in entries)
{
- var entryState = entry.Value.IsValid;
- if (entryState == null)
+ var entryState = entry.Value.ValidationState;
+ if (entryState == ModelValidationState.Unvalidated)
{
// If any entries of a field is unvalidated, we'll treat the tree as unvalidated.
- return null;
+ return entryState;
}
- else if (!entryState.Value)
+ else if (entryState == ModelValidationState.Invalid)
{
- state = false;
+ validationState = entryState;
}
}
- return state;
+ return validationState;
}
#region IDictionary members
diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelValidationState.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelValidationState.cs
new file mode 100644
index 0000000000..cec29a1cd8
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelValidationState.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Open Technologies, Inc.
+// All Rights Reserved
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
+// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
+// NON-INFRINGEMENT.
+// See the Apache 2 License for the specific language governing
+// permissions and limitations under the License.
+
+namespace Microsoft.AspNet.Mvc.ModelBinding
+{
+ public enum ModelValidationState
+ {
+ Unvalidated,
+ Invalid,
+ Valid,
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs
index d9b440b0b2..6e876012d3 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs
@@ -402,12 +402,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
ModelState modelState;
Assert.True(modelStateDictionary.TryGetValue("theModel.Name", out modelState));
Assert.Equal(0, modelState.Errors.Count);
- Assert.Equal(true, modelState.IsValid);
+ Assert.Equal(ModelValidationState.Valid, modelState.ValidationState);
// Check Age error.
Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState));
Assert.Equal(1, modelState.Errors.Count);
- Assert.Equal(false, modelState.IsValid);
+ Assert.Equal(ModelValidationState.Invalid, modelState.ValidationState);
var modelError = modelState.Errors[0];
Assert.Null(modelError.Exception);
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ModelStateDictionaryTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ModelStateDictionaryTest.cs
index 81bb3e0c09..1e5353d82e 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ModelStateDictionaryTest.cs
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ModelStateDictionaryTest.cs
@@ -121,9 +121,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void IsValidFieldReturnsTrueIfModelStateDoesNotContainErrors()
{
// Arrange
- var msd = new ModelStateDictionary()
+ var validState = new ModelState
{
- { "foo", new ModelState() { Value = new ValueProviderResult(null, null, null), IsValid = true } }
+ Value = new ValueProviderResult(null, null, null),
+ ValidationState = ModelValidationState.Valid
+ };
+ var msd = new ModelStateDictionary
+ {
+ { "foo", validState }
};
// Act
@@ -137,19 +142,30 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void IsValidPropertyReturnsFalseIfErrors()
{
// Arrange
- var errorState = new ModelState() { Value = GetValueProviderResult("quux", "quux"), IsValid = false };
+ var errorState = new ModelState
+ {
+ Value = GetValueProviderResult("quux", "quux"),
+ ValidationState = ModelValidationState.Invalid
+ };
+ var validState = new ModelState
+ {
+ Value = GetValueProviderResult("bar", "bar"),
+ ValidationState = ModelValidationState.Valid
+ };
errorState.Errors.Add("some error");
var dictionary = new ModelStateDictionary()
{
- { "foo", new ModelState() { Value = GetValueProviderResult("bar", "bar"), IsValid = true } },
+ { "foo", validState },
{ "baz", errorState }
};
// Act
var isValid = dictionary.IsValid;
+ var validationState = dictionary.ValidationState;
// Assert
- Assert.Equal(false, isValid);
+ Assert.False(isValid);
+ Assert.Equal(ModelValidationState.Invalid, validationState);
}
[Fact]
@@ -158,15 +174,58 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var dictionary = new ModelStateDictionary()
{
- { "foo", new ModelState() { IsValid = true, Value = GetValueProviderResult("bar", "bar") } },
- { "baz", new ModelState() { IsValid = true, Value = GetValueProviderResult("quux", "bar") } }
+ { "foo", new ModelState
+ {
+ ValidationState = ModelValidationState.Valid,
+ Value = GetValueProviderResult("bar", "bar")
+ }
+ },
+ { "baz", new ModelState
+ {
+ ValidationState = ModelValidationState.Valid,
+ Value = GetValueProviderResult("quux", "bar")
+ }
+ }
};
// Act
var isValid = dictionary.IsValid;
+ var validationState = dictionary.ValidationState;
// Assert
- Assert.Equal(true, isValid);
+ Assert.True(isValid);
+ Assert.Equal(ModelValidationState.Valid, validationState);
+ }
+
+ [Fact]
+ public void IsValidPropertyReturnsFalse_IfSomeFieldsAreNotValidated()
+ {
+ // Arrange
+ var errorState = new ModelState
+ {
+ Value = GetValueProviderResult("quux", "quux"),
+ ValidationState = ModelValidationState.Invalid
+ };
+ var validState = new ModelState
+ {
+ Value = GetValueProviderResult("bar", "bar"),
+ ValidationState = ModelValidationState.Valid
+ };
+ errorState.Errors.Add("some error");
+ var dictionary = new ModelStateDictionary()
+ {
+ { "foo", validState },
+ { "baz", errorState },
+ { "qux", new ModelState { Value = GetValueProviderResult() }}
+ };
+
+ // Act
+ var isValid = dictionary.IsValid;
+ var validationState = dictionary.ValidationState;
+
+ // Assert
+ Assert.False(isValid);
+ Assert.Equal(ModelValidationState.Unvalidated, validationState);
}
[Fact]
@@ -254,7 +313,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var dictionary = new ModelStateDictionary();
- dictionary["user.Address"] = new ModelState { IsValid = true };
+ dictionary["user.Address"] = new ModelState { ValidationState = ModelValidationState.Valid };
dictionary.SetModelValue("user.Name", GetValueProviderResult());
dictionary.AddModelError("user.Age", "Age is not a valid int");
@@ -272,8 +331,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var dictionary = new ModelStateDictionary();
- dictionary["user.Address"] = new ModelState { IsValid = true };
- dictionary["user.Name"] = new ModelState { IsValid = true };
+ dictionary["user.Address"] = new ModelState { ValidationState = ModelValidationState.Valid };
+ dictionary["user.Name"] = new ModelState { ValidationState = ModelValidationState.Valid };
dictionary.AddModelError("user.Age", "Age is not a valid int");
// Act
@@ -288,8 +347,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var dictionary = new ModelStateDictionary();
- dictionary["user.Address"] = new ModelState { IsValid = true };
- dictionary["user.Name"] = new ModelState { IsValid = true };
+ dictionary["user.Address"] = new ModelState { ValidationState = ModelValidationState.Valid };
+ dictionary["user.Name"] = new ModelState { ValidationState = ModelValidationState.Valid };
// Act
var isValidField = dictionary.IsValidField("user");
@@ -300,8 +359,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private static ValueProviderResult GetValueProviderResult(object rawValue = null, string attemptedValue = null)
{
- return new ValueProviderResult(rawValue ?? "some value",
- attemptedValue ?? "some value",
+ return new ValueProviderResult(rawValue ?? "some value",
+ attemptedValue ?? "some value",
CultureInfo.InvariantCulture);
}
}