A change in CompositeModelValidator.Validate method breaking some functionality of existing applications.
MVC 4,
```
public override IEnumerable<ModelValidationResult> Validate(object container)
{
bool propertiesValid = true;
foreach (ModelMetadata propertyMetadata in Metadata.Properties)
{
foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model))
{
propertiesValid = false;
yield return new ModelValidationResult
{
MemberName = DefaultModelBinder.CreateSubPropertyName(propertyMetadata.PropertyName, propertyResult.MemberName),
Message = propertyResult.Message
};
}
}
}
if (propertiesValid)
{
foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult typeResult in typeValidator.Validate(container))
{
yield return typeResult;
}
}
}
}
```
MVC 5,
```
public override IEnumerable<ModelValidationResult> Validate(object container)
{
bool propertiesValid = true;
ModelMetadata[] properties = Metadata.PropertiesAsArray;
// Performance sensitive loops
for (int propertyIndex = 0; propertyIndex < properties.Length; propertyIndex++)
{
ModelMetadata propertyMetadata = properties[propertyIndex];
foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model))
{
propertiesValid = false;
yield return CreateSubPropertyResult(propertyMetadata, propertyResult);
}
}
}
if (propertiesValid)
{
foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult typeResult in typeValidator.Validate(container))
{
yield return typeResult;
}
}
}
}
```
Pre MVC 5 calling the property getter again before triggering validation. But MVC 5 doesn't. For detail please see,
http://forums.asp.net/t/1962641.aspx?Data+annotation+model+validation+in+MVC5+different+than+in+MVC3
MVC 4,
```
public override IEnumerable<ModelValidationResult> Validate(object container)
{
bool propertiesValid = true;
foreach (ModelMetadata propertyMetadata in Metadata.Properties)
{
foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model))
{
propertiesValid = false;
yield return new ModelValidationResult
{
MemberName = DefaultModelBinder.CreateSubPropertyName(propertyMetadata.PropertyName, propertyResult.MemberName),
Message = propertyResult.Message
};
}
}
}
if (propertiesValid)
{
foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult typeResult in typeValidator.Validate(container))
{
yield return typeResult;
}
}
}
}
```
MVC 5,
```
public override IEnumerable<ModelValidationResult> Validate(object container)
{
bool propertiesValid = true;
ModelMetadata[] properties = Metadata.PropertiesAsArray;
// Performance sensitive loops
for (int propertyIndex = 0; propertyIndex < properties.Length; propertyIndex++)
{
ModelMetadata propertyMetadata = properties[propertyIndex];
foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model))
{
propertiesValid = false;
yield return CreateSubPropertyResult(propertyMetadata, propertyResult);
}
}
}
if (propertiesValid)
{
foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext))
{
foreach (ModelValidationResult typeResult in typeValidator.Validate(container))
{
yield return typeResult;
}
}
}
}
```
Pre MVC 5 calling the property getter again before triggering validation. But MVC 5 doesn't. For detail please see,
http://forums.asp.net/t/1962641.aspx?Data+annotation+model+validation+in+MVC5+different+than+in+MVC3