diff --git a/CaPPMS/Attributes/CappmsStringLengthAttribute.cs b/CaPPMS/Attributes/CappmsStringLengthAttribute.cs
new file mode 100644
index 0000000..196ae3a
--- /dev/null
+++ b/CaPPMS/Attributes/CappmsStringLengthAttribute.cs
@@ -0,0 +1,52 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace CaPPMS.Attributes
+{
+ ///
+ /// Provides a custom string length attribute that includes the current length of the string in the error message.
+ ///
+ public class CappmsStringLengthAttribute : StringLengthAttribute
+ {
+ private string? context;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The maximum length of the object shall be.
+ public CappmsStringLengthAttribute(int maximumLength) : base(maximumLength)
+ {
+ }
+
+ ///
+ /// Override the default IsValid method to store the current string value.
+ ///
+ /// The object to validate.
+ /// true if valid.
+ public override bool IsValid(object? value)
+ {
+ if (value is string str)
+ {
+ this.context = str;
+ }
+
+ return base.IsValid(value);
+ }
+
+ ///
+ /// Override the default error message to include the current length of the string.
+ ///
+ /// Property Name.
+ /// A formatted message.
+ public override string FormatErrorMessage(string name)
+ {
+ if (this.context != null)
+ {
+ string message = base.FormatErrorMessage(name);
+ message += $" Current length:{this.context.Length}.";
+ return message;
+ }
+
+ return base.FormatErrorMessage(name);
+ }
+ }
+}
diff --git a/CaPPMS/CaPPMS.sln b/CaPPMS/CaPPMS.sln
index c50d584..f9d79b0 100644
--- a/CaPPMS/CaPPMS.sln
+++ b/CaPPMS/CaPPMS.sln
@@ -1,6 +1,12 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35913.81 d17.13
+MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CaPPMS", "CaPPMS.csproj", "{AA9B970F-5351-4EA2-A78C-7E83F05C57C1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaPPMSTests", "..\CaPPMSTests\CaPPMSTests.csproj", "{5A356024-F9CF-BC44-22A7-4FEE4DBA2663}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -11,6 +17,10 @@ Global
{AA9B970F-5351-4EA2-A78C-7E83F05C57C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA9B970F-5351-4EA2-A78C-7E83F05C57C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA9B970F-5351-4EA2-A78C-7E83F05C57C1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5A356024-F9CF-BC44-22A7-4FEE4DBA2663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5A356024-F9CF-BC44-22A7-4FEE4DBA2663}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5A356024-F9CF-BC44-22A7-4FEE4DBA2663}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5A356024-F9CF-BC44-22A7-4FEE4DBA2663}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/CaPPMS/Model/Review.cs b/CaPPMS/Model/Review.cs
index 76e0adb..b4e9361 100644
--- a/CaPPMS/Model/Review.cs
+++ b/CaPPMS/Model/Review.cs
@@ -7,6 +7,11 @@ namespace CaPPMS.Model
[SqlTableName("StudentReviews")]
public class Review : ISqlTableModel
{
+ ///
+ /// The maximum length of a string in the database.
+ ///
+ public const int MaxStringLength = 4 * 1024;
+
public Review() { }
[SqlIdProperty]
@@ -29,7 +34,10 @@ public Review() { }
public string Score { get; set; } = "0";
[Required(ErrorMessage = "Your comments for the student are appreciated.", AllowEmptyStrings = false)]
- [StringLength(maximumLength: 255, MinimumLength = 25, ErrorMessage = "Please use at least 25 characters to describe the interaction of this student.")]
+ [CappmsStringLength(
+ maximumLength: MaxStringLength,
+ MinimumLength = 25,
+ ErrorMessage = "Please use at least {2} characters to describe the interaction of this student and at most {1} characters.")]
public string Comments { get; set; } = string.Empty;
}
}
\ No newline at end of file
diff --git a/CaPPMSTests/Attribute/CappmsStringLengthAttributeTests.cs b/CaPPMSTests/Attribute/CappmsStringLengthAttributeTests.cs
new file mode 100644
index 0000000..b97ee49
--- /dev/null
+++ b/CaPPMSTests/Attribute/CappmsStringLengthAttributeTests.cs
@@ -0,0 +1,55 @@
+using CaPPMS.Attributes;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Threading.Tasks;
+
+namespace CaPPMSTests.Attribute
+{
+ [TestClass]
+ public class CappmsStringLengthAttributeTests
+ {
+ [TestMethod]
+ public async Task StringIsValid()
+ {
+ // Arrange
+ var attribute = new CappmsStringLengthAttribute(100)
+ {
+ MinimumLength = 5,
+ };
+
+ string value = "This is a test string.";
+ Assert.IsTrue(attribute.IsValid(value));
+ await Task.CompletedTask;
+ }
+
+ [TestMethod]
+ public async Task StringIsInvalidMinLen()
+ {
+ // Arrange
+ var attribute = new CappmsStringLengthAttribute(100)
+ {
+ MinimumLength = 5,
+ };
+ string value = "Test";
+ Assert.IsFalse(attribute.IsValid(value));
+ string errorMessage = attribute.FormatErrorMessage("Test");
+ Assert.AreEqual("The field Test must be a string with a minimum length of 5 and a maximum length of 100. Current length:4.", errorMessage);
+
+ await Task.CompletedTask;
+ }
+
+ [TestMethod]
+ public async Task StringIsInvalidMaxLen()
+ {
+ // Arrange
+ var attribute = new CappmsStringLengthAttribute(10)
+ {
+ MinimumLength = 5,
+ };
+ string value = "This is a test string.";
+ Assert.IsFalse(attribute.IsValid(value));
+ string errorMessage = attribute.FormatErrorMessage("Test");
+ Assert.AreEqual("The field Test must be a string with a minimum length of 5 and a maximum length of 10. Current length:22.", errorMessage);
+ await Task.CompletedTask;
+ }
+ }
+}
diff --git a/CaPPMSTests/Model/Table/TableTests.cs b/CaPPMSTests/Model/Table/TableTests.cs
index 2ed13fc..fe316e3 100644
--- a/CaPPMSTests/Model/Table/TableTests.cs
+++ b/CaPPMSTests/Model/Table/TableTests.cs
@@ -1,4 +1,5 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using CaPPMS.Model;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CaPPMSTests.Model.Table
{
@@ -8,7 +9,7 @@ public class TableTests
[TestMethod]
public void NumberOfColumns()
{
- var table = new CaPPMS.Model.Table.Table()
+ var table = new CaPPMS.Model.Table.Table()
{
DataSource = new IEnumberableDummyObject()
};
@@ -19,7 +20,7 @@ public void NumberOfColumns()
[TestMethod]
public void ColumnNames()
{
- var table = new CaPPMS.Model.Table.Table()
+ var table = new CaPPMS.Model.Table.Table()
{
DataSource = new IEnumberableDummyObject()
};
@@ -31,7 +32,7 @@ public void ColumnNames()
[TestMethod]
public void VerifySingleRow()
{
- var table = new CaPPMS.Model.Table.Table()
+ var table = new CaPPMS.Model.Table.Table()
{
DataSource = new IEnumberableDummyObject()
};