Skip to content

Commit

Permalink
Merge pull request #3 from dbuenor/dbueno/add-MinElementsIfAttribute
Browse files Browse the repository at this point in the history
Added new Conditional Validation attributes for MinElements (@2.5h)
  • Loading branch information
dbuenor committed May 5, 2016
2 parents 2b83d01 + 0ab07ab commit 8fc03d9
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 7 deletions.
Expand Up @@ -50,6 +50,7 @@
<Compile Include="NotEqualToAttributeTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RegularExpressionIfAttributeTest.cs" />
<Compile Include="MinElementsIfAttributeTest.cs" />
<Compile Include="RequiredIfAttributeTest.cs" />
<Compile Include="RequiredIfEmptyAttributeTest.cs" />
<Compile Include="RequiredIfFalseAttributeTest.cs" />
Expand Down
80 changes: 80 additions & 0 deletions HermaFx.DataAnnotations.Tests/MinElementsIfAttributeTest.cs
@@ -0,0 +1,80 @@

using NUnit.Framework;
using System;

namespace HermaFx.DataAnnotations
{
[TestFixture]
public class MinElementsIfAttributeTest
{
private class Model : ModelBase<MinElementsIfAttribute>
{
public string Value1 { get; set; }

[MinElementsIf(3, "Value1", "hello")]
public string[] Value2 { get; set; }
}

private class ComplexModel : ModelBase<MinElementsIfAttribute>
{
public class SubModel
{
public string InnerValue { get; set; }
}

public SubModel Value1 { get; set; }

[MinElementsIf(3, "Value1.InnerValue", "hello")]
public string[] Value2 { get; set; }
}

[Test]
public void IsValidTest()
{
var model = new Model() { Value1 = "hello", Value2 = new string[] { "hello", "hello2", "hello3" } };
Assert.IsTrue(model.IsValid("Value2"));
}

[Test]
public void IsValidTestComplex()
{
var model = new ComplexModel() {Value1 = new ComplexModel.SubModel() {InnerValue = "hello"}, Value2 = new string[] { "bla", "bla2", "bla3" } };
Assert.IsTrue(model.IsValid("Value2"));
}

[Test]
public void IsNotValidTest()
{
var model = new Model() { Value1 = "hello", Value2 = new string[] { "hello", "hello2" } };
Assert.IsFalse(model.IsValid("Value2"));
}

[Test]
public void IsNotValidTestComplex()
{
var model = new ComplexModel() { Value1 = new ComplexModel.SubModel() { InnerValue = "hello" }, Value2 = new string[] { "bla", "bla2" } };
Assert.IsFalse(model.IsValid("Value2"));
}

[Test]
public void IsValidWithValue2NullTest()
{
var model = new Model() { Value1 = "hello", Value2 = null };
Assert.IsTrue(model.IsValid("Value2"));
}

[Test]
public void IsNotRequiredToHaveMinElementsTest()
{
var model = new Model() { Value1 = "goodbye" };
Assert.IsTrue(model.IsValid("Value2"));
}

[Test]
public void IsNotRequiredToHaveMinElementsWithValue1NullTest()
{
var model = new Model() { Value1 = null };
Assert.IsTrue(model.IsValid("Value2"));
}
}
}
4 changes: 4 additions & 0 deletions HermaFx.DataAnnotations/HermaFx.DataAnnotations.csproj
Expand Up @@ -51,8 +51,12 @@
<Compile Include="AggregateValidationException.cs" />
<Compile Include="AggregateValidationResult.cs" />
<Compile Include="IPAddressAttribute.cs" />
<Compile Include="MinElementsIfAttribute.cs" />
<Compile Include="NotDefaultAttribute.cs" />
<Compile Include="ContainsStringAttribute.cs" />
<Compile Include="MinElementsIfNotAttribute.cs" />
<Compile Include="MinElementsIfHasFlagAttribute.cs" />
<Compile Include="MinElementsIfNotHasFlagAttribute.cs" />
<Compile Include="ValidateElementsUsingAttribute.cs" />
<Compile Include="ContingentValidationAttribute.cs" />
<Compile Include="MaxElementsAttribute.cs" />
Expand Down
10 changes: 5 additions & 5 deletions HermaFx.DataAnnotations/MinElementsAttribute.cs
Expand Up @@ -11,12 +11,12 @@ public class MinElementsAttribute : ValidationAttribute
{
private const string _defaultErrorMessage = "There should be at least {0} elements.";

private uint _elements;
public uint Elements;

public MinElementsAttribute(uint elements)
: base(() => GetErrorMessage(elements))
{
_elements = elements;
Elements = elements;
}

private static string GetErrorMessage(uint elements)
Expand All @@ -27,9 +27,9 @@ private static string GetErrorMessage(uint elements)
public override bool IsValid(object value)
{
if (value == null) return true;
if (value is Array) return (value as Array).Length >= _elements;
if (value is ICollection) return (value as ICollection).Count >= _elements;
if (value is IEnumerable) return (value as IEnumerable).OfType<object>().Count() >= _elements;
if (value is Array) return (value as Array).Length >= Elements;
if (value is ICollection) return (value as ICollection).Count >= Elements;
if (value is IEnumerable) return (value as IEnumerable).OfType<object>().Count() >= Elements;

return false;
}
Expand Down
69 changes: 69 additions & 0 deletions HermaFx.DataAnnotations/MinElementsIfAttribute.cs
@@ -0,0 +1,69 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HermaFx.DataAnnotations
{
public class MinElementsIfAttribute : ContingentValidationAttribute
{
public Operator Operator { get; private set; }
public object DependentValue { get; private set; }
private MinElementsAttribute MinElements{ get; set; }
/// <summary>
/// Gets or sets a flag indicating whether the attribute should allow empty strings.
/// </summary>
public bool AllowEmptyStrings { get; set; }
protected OperatorMetadata Metadata { get; private set; }

public MinElementsIfAttribute(uint elements, string dependentProperty, Operator @operator, object dependentValue)
: base(dependentProperty)
{
Operator = @operator;
DependentValue = dependentValue;
Metadata = OperatorMetadata.Get(Operator);
MinElements = new MinElementsAttribute(elements);
}

public MinElementsIfAttribute(uint elements, string dependentProperty, object dependentValue)
: this(elements, dependentProperty, Operator.EqualTo, dependentValue) { }

public override string FormatErrorMessage(string name)
{
if (string.IsNullOrEmpty(ErrorMessageResourceName) && string.IsNullOrEmpty(ErrorMessage))
ErrorMessage = DefaultErrorMessage;

return MinElements.ErrorMessage;
}

public override string ClientTypeName
{
get { return "MinElementsIf"; }
}

protected override IEnumerable<KeyValuePair<string, object>> GetClientValidationParameters()
{
return base.GetClientValidationParameters()
.Union(new[] {
new KeyValuePair<string, object>("Operator", Operator.ToString()),
new KeyValuePair<string, object>("DependentValue", DependentValue),
new KeyValuePair<string, object>("Elements", MinElements.Elements),
});
}

public override bool IsValid(object value, object dependentValue, object container)
{
if (Metadata.IsValid(dependentValue, DependentValue))
return MinElements.IsValid(value);

return true;
}

public override string DefaultErrorMessage
{
get { return MinElements.ErrorMessage; }
}
}
}
13 changes: 13 additions & 0 deletions HermaFx.DataAnnotations/MinElementsIfHasFlagAttribute.cs
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HermaFx.DataAnnotations
{
public class MinElementsIfHasFlagAttribute : MinElementsIfAttribute
{
public MinElementsIfHasFlagAttribute(uint elements, string dependentProperty, object flags) : base(elements, dependentProperty, Operator.HasFlag, flags) { }
}
}
17 changes: 17 additions & 0 deletions HermaFx.DataAnnotations/MinElementsIfNotAttribute.cs
@@ -0,0 +1,17 @@
#region LICENSE
// Source Code licensed under MS-PL.
// Derived from: MVC Foolproof Validation (http://foolproof.codeplex.com/)
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HermaFx.DataAnnotations
{
public class MinElementsIfNotAttribute : MinElementsIfAttribute
{
public MinElementsIfNotAttribute(uint elements, string dependentProperty, object dependentValue) : base(elements, dependentProperty, Operator.NotEqualTo, dependentValue) { }
}
}
13 changes: 13 additions & 0 deletions HermaFx.DataAnnotations/MinElementsIfNotHasFlagAttribute.cs
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HermaFx.DataAnnotations
{
public class MinElementsIfNotHasFlagAttribute : MinElementsIfAttribute
{
public MinElementsIfNotHasFlagAttribute(uint elements, string dependentProperty, object flags) : base(elements, dependentProperty, Operator.NotHasFlag, flags) { }
}
}
4 changes: 2 additions & 2 deletions HermaFx.DataAnnotations/RequiredIfAttribute.cs
@@ -1,6 +1,6 @@
#region LICENSE
// Source Code licensed under MS-PL.
// Derived from: MVC Foolproof Validation (http://foolproof.codeplex.com/)
// Derived from: MVC Foolproof Validation (http://foolproof.codeplex.com/)
# endregion
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -60,7 +60,7 @@ public override bool IsValid(object value, object dependentValue, object contain
if (value == null) return false;
if (value is string) return AllowEmptyStrings ? true : (value as string).Length > 0;
}

return true;
}

Expand Down

0 comments on commit 8fc03d9

Please sign in to comment.