从 C# 中的 StringLengthAttribute 获取当前长度
Get the current length from StringLengthAttribute in C#
我在模型中有 ASP.NET 个网站属性:
[Required]
[Display(Name = "bla bla")]
[MinMaxLength(50,2000)]
public string TextDetail { get; set; }
而且我已经本地化了
public class MinMaxLengthAttribute : StringLengthAttribute
{
public MinMaxLengthAttribute(int minimum, int maximum)
:base(maximum)
{
ErrorMessage = "{0} must contain from {2} to {1} characters."; //this text is localized, that is why I need to use special class
MinimumLength = minimum;
}
}
当我查看日志时,我可以找到
Exception (level 0):
Message = bla bla must contain from 50 to 2000 characters.
如果用户写的字符串太短或太长,我想记录。有没有办法在 StringLengthAttribute 中记录字符串的当前长度?
最后,解决方法很简单:
public class MinMaxLengthAttribute : StringLengthAttribute
{
int? _stringLength = null;
public MinMaxLengthAttribute(int minimum, int maximum)
: base(maximum)
{
SetErrorMessage();
MinimumLength = minimum;
}
void SetErrorMessage()
{
ErrorMessage = "{0} must contain {2} to {1} characters." +
" It contains " + (_stringLength ?? -1) + " characters.";
}
public override bool IsValid(object value)
{
string s = value as string;
if (s != null)
{
_stringLength = s.Length;
SetErrorMessage();
}
return base.IsValid(value);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string s = value as string;
if (s != null)
{
_stringLength = s.Length;
SetErrorMessage();
}
return base.IsValid(value, validationContext);
}
}
和单元测试:
using Common.Validators;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Test.Model
{
[TestClass]
public class UnitTestDtaValidation
{
[TestMethod]
public void TestMinMaxLengthAttribute()
{
MyModel model = new MyModel()
{
TextDetail = "a"
};
var validationContext = new ValidationContext(model, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = System.ComponentModel.DataAnnotations.Validator.TryValidateObject(model, validationContext, results, true);
Assert.IsFalse(isValid);
Assert.AreEqual(1, results.Count);
Assert.AreEqual("Description must contain from 5 to 10 characters. It contains 1 characters.", results[0].ErrorMessage);
}
}
public class MyModel
{
[Required]
[Display(Name = "Description")]
[MinMaxLength(5, 10)]
public string TextDetail { get; set; }
}
}
您可以像下面这样使用 StringLengthAttribute
:
[Required]
[Display(Name = "bla bla")]
[StringLength(20000, MinimumLength = 50, ErrorMessage = "{0} must contain from {2} to {1} characters.")]
public string TextDetail { get; set; }
而且,如果要显示当前无效值,可以使用jQuery。不需要服务器端代码来做这么简单的事情。
StringLengthAttribute
class 继承自 ValidationAttribute
,可以使用 ErrorMessageResourceType
和 ErrorMessageResourceName
从资源字符串本地化。所以你的例子变成:
public class MyModel
{
[Required]
[Display(Name = "Description")]
[StringLength(10, MinimumLength = 5, ErrorMessageResourceType = typeof(MyStringsResource), ErrorMessageResourceName = "MyTextDetailErrorMessage"]
public string TextDetail { get; set; }
}
并且在您本地化的 MyStringsResource
资源中,将名为 MyTextDetailErrorMessage
的字符串设置为 "{0} must contain {2} to {1} characters."
.
如果您需要派生的 class 中的更动态的消息,您可以使用受保护的重载 ValidationAttribute(Func<string> errorMessageAccessor)
构造 MinMaxLengthAttribute
实例,它允许您提供一个函数来查找错误信息。抱歉,我没有经验可以分享。
我在模型中有 ASP.NET 个网站属性:
[Required]
[Display(Name = "bla bla")]
[MinMaxLength(50,2000)]
public string TextDetail { get; set; }
而且我已经本地化了
public class MinMaxLengthAttribute : StringLengthAttribute
{
public MinMaxLengthAttribute(int minimum, int maximum)
:base(maximum)
{
ErrorMessage = "{0} must contain from {2} to {1} characters."; //this text is localized, that is why I need to use special class
MinimumLength = minimum;
}
}
当我查看日志时,我可以找到
Exception (level 0):
Message = bla bla must contain from 50 to 2000 characters.
如果用户写的字符串太短或太长,我想记录。有没有办法在 StringLengthAttribute 中记录字符串的当前长度?
最后,解决方法很简单:
public class MinMaxLengthAttribute : StringLengthAttribute
{
int? _stringLength = null;
public MinMaxLengthAttribute(int minimum, int maximum)
: base(maximum)
{
SetErrorMessage();
MinimumLength = minimum;
}
void SetErrorMessage()
{
ErrorMessage = "{0} must contain {2} to {1} characters." +
" It contains " + (_stringLength ?? -1) + " characters.";
}
public override bool IsValid(object value)
{
string s = value as string;
if (s != null)
{
_stringLength = s.Length;
SetErrorMessage();
}
return base.IsValid(value);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string s = value as string;
if (s != null)
{
_stringLength = s.Length;
SetErrorMessage();
}
return base.IsValid(value, validationContext);
}
}
和单元测试:
using Common.Validators;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Test.Model
{
[TestClass]
public class UnitTestDtaValidation
{
[TestMethod]
public void TestMinMaxLengthAttribute()
{
MyModel model = new MyModel()
{
TextDetail = "a"
};
var validationContext = new ValidationContext(model, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = System.ComponentModel.DataAnnotations.Validator.TryValidateObject(model, validationContext, results, true);
Assert.IsFalse(isValid);
Assert.AreEqual(1, results.Count);
Assert.AreEqual("Description must contain from 5 to 10 characters. It contains 1 characters.", results[0].ErrorMessage);
}
}
public class MyModel
{
[Required]
[Display(Name = "Description")]
[MinMaxLength(5, 10)]
public string TextDetail { get; set; }
}
}
您可以像下面这样使用 StringLengthAttribute
:
[Required]
[Display(Name = "bla bla")]
[StringLength(20000, MinimumLength = 50, ErrorMessage = "{0} must contain from {2} to {1} characters.")]
public string TextDetail { get; set; }
而且,如果要显示当前无效值,可以使用jQuery。不需要服务器端代码来做这么简单的事情。
StringLengthAttribute
class 继承自 ValidationAttribute
,可以使用 ErrorMessageResourceType
和 ErrorMessageResourceName
从资源字符串本地化。所以你的例子变成:
public class MyModel
{
[Required]
[Display(Name = "Description")]
[StringLength(10, MinimumLength = 5, ErrorMessageResourceType = typeof(MyStringsResource), ErrorMessageResourceName = "MyTextDetailErrorMessage"]
public string TextDetail { get; set; }
}
并且在您本地化的 MyStringsResource
资源中,将名为 MyTextDetailErrorMessage
的字符串设置为 "{0} must contain {2} to {1} characters."
.
如果您需要派生的 class 中的更动态的消息,您可以使用受保护的重载 ValidationAttribute(Func<string> errorMessageAccessor)
构造 MinMaxLengthAttribute
实例,它允许您提供一个函数来查找错误信息。抱歉,我没有经验可以分享。