从C#中的StringLengthAttribute获取当前长度

时间:2015-01-07 19:54:20

标签: asp.net-mvc validation data-annotations

我在模型中有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中记录当前字符串的长度?

3 个答案:

答案 0 :(得分:2)

您可以使用下面的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。服务器端代码不需要做这么简单的事情。

答案 1 :(得分:0)

StringLengthAttribute类继承自ValidationAttribute,可以使用ErrorMessageResourceTypeErrorMessageResourceName从资源字符串进行本地化。因此,您的示例变为:

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."的内容。

如果在派生类中需要更多动态消息,则可以使用受保护的重载MinMaxLengthAttribute来构建ValidationAttribute(Func<string> errorMessageAccessor)实例,该重载可以让您提供查找错误消息的功能。抱歉,我没有分享经验。

答案 2 :(得分:-1)

最后,解决方案非常简单:

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; }
    }

}