diff --git a/README.md b/README.md index b106245..c4a4dbd 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,21 @@ Therefore they are exposed as extension methods in the C# api and are suffixed w #### ASP.NET Core MVC -CoordinationNumberAttribute: To be added. +If used to validate input in an ASP.NET Core MVC project, the `CoordinationNumberAttribute` can be used like this: + +```c# +public class SampleDataModel +{ + [CoordinationNumber] + public string CoordinationNumber { get; set; } +} +``` + +The `CoordinationNumberAttribute` attribute is available through a separate package: + +```console +dotnet add package ActiveLogin.Identity.Swedish.AspNetCore +``` ### 3. Use the library in your F# project diff --git a/src/ActiveLogin.Identity.Swedish.AspNetCore/Validation/CoordinationNumberAttribute.cs b/src/ActiveLogin.Identity.Swedish.AspNetCore/Validation/CoordinationNumberAttribute.cs new file mode 100644 index 0000000..3292c0c --- /dev/null +++ b/src/ActiveLogin.Identity.Swedish.AspNetCore/Validation/CoordinationNumberAttribute.cs @@ -0,0 +1,43 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace ActiveLogin.Identity.Swedish.AspNetCore.Validation +{ + /// + /// Validates a Swedish Coordination Number using . + /// + public class CoordinationNumberAttribute : ValidationAttribute + { + /// Initializes a new instance of the class. + public CoordinationNumberAttribute() + : base("{0} is not a valid Swedish Coordination Number. It should follow a valid pattern such as YYMMDD-IIIC, YYMMDD+IIIC or YYYYMMDDIIIC.") + { } + + /// Initializes a new instance of the class by using the function that enables access to validation resources. + /// The function that enables access to validation resources. + /// errorMessageAccessor is null. + public CoordinationNumberAttribute(Func errorMessageAccessor) : base(errorMessageAccessor) + { } + + /// Initializes a new instance of the class by using the error message to associate with a validation control. + /// The error message to associate with a validation control. + public CoordinationNumberAttribute(string errorMessage) : base(errorMessage) + { } + + /// Validates the specified Swedish Coordination Number with respect to the current validation attribute. + /// The Swedish Coordination Number to validate. + /// The context information about the validation operation. + /// An instance of the class. + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + var valueString = (string) value; + if (!CoordinationNumber.TryParse(valueString, out _)) + { + var errorMessage = FormatErrorMessage(validationContext.DisplayName); + return new ValidationResult(errorMessage); + } + + return ValidationResult.Success; + } + } +} diff --git a/test/ActiveLogin.Identity.Swedish.AspNetCore.Test/Validation/SwedishCoordinationNumberAttribute_IsValid.cs b/test/ActiveLogin.Identity.Swedish.AspNetCore.Test/Validation/SwedishCoordinationNumberAttribute_IsValid.cs new file mode 100644 index 0000000..78c6884 --- /dev/null +++ b/test/ActiveLogin.Identity.Swedish.AspNetCore.Test/Validation/SwedishCoordinationNumberAttribute_IsValid.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using ActiveLogin.Identity.Swedish.AspNetCore.Validation; +using Xunit; + +namespace ActiveLogin.Identity.Swedish.AspNetCore.Test.Validation +{ + /// + /// Tested with official test Coordination Numbers from Skatteverket: + /// https://swedish.identityinfo.net/coordinationnumber/testdata + /// + public class SwedishCoordinationNumberAttribute_IsValid + { + [Fact] + public void Returns_Valid_When_Valid_Coordination_Number() + { + var model = new SampleValidationModel("480977-2389"); + var context = new ValidationContext(model); + var results = new List(); + var isValid = Validator.TryValidateObject(model, context, results, true); + + Assert.True(isValid); + Assert.Empty(results); + } + + [Fact] + public void Returns_Invalid_When_Invalid_Coordination_Number() + { + var model = new SampleValidationModel("A"); + var context = new ValidationContext(model); + var results = new List(); + var isValid = Validator.TryValidateObject(model, context, results, true); + + Assert.False(isValid); + Assert.Single(results); + } + + private class SampleValidationModel + { + public SampleValidationModel(string swedishCoordinationNumber) + { + SwedishCoordinationNumber = swedishCoordinationNumber; + } + + [CoordinationNumber] + public string SwedishCoordinationNumber { get; } + } + } +}