正则表达式停止崩溃

时间:2012-01-15 01:37:54

标签: c# regex

考虑以下代码:

[Required]
[RegularExpression(@"\d{2,2}/\d{2,2}/\d{4,4} \d{2,2}:\d{2,2}:\d{2,2}", 
ErrorMessage = "Wrong Syntax Entered, Needed:day/Month/Year Hour:Minutes:Seconds")]
public DateTime Posted { get; set; }

当我输入此值时,我的应用程序崩溃:00/00/0000 00:00:00

有没有办法阻止这种情况并使其更加逼真?我想要允许日期,所以它只允许最多31天或更少1,并允许最多12个月和1分钟?

4 个答案:

答案 0 :(得分:2)

正则表达式是验证日期和时间的错误方法。请改用DateTime.TryParse

编辑:

以下是一个例子:

using System;
using System.Globalization;

...

bool valid;
DateTime dt;
valid = DateTime.TryParseExact(inputString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);

答案 1 :(得分:0)

我同意@MRAB,TryParse可能更容易管理和维护。

SO question也尝试执行您正在执行的操作,并创建了一个自定义属性(源自RegularExpressionAttribute),似乎已解决了他的问题。也许它会帮助你。

希望这有帮助。

答案 2 :(得分:0)

使用Regex验证数据时间将导致复杂的正则表达式,如

^([0][1-9]||[1-2][0-9]||[3][0-1])/([0][1-9]||[1][1-2])/([1][0-9]{3}) ([0][1-9]||[1][0-2]):([0][1-9]||[1-5][0-9]):([0][1-9]||[1-5][0-9])$

但我仍怀疑它可能会遗漏一些优势案例。

如果您使用的是MVC3,那么使用自我验证模型的最佳方式如下,

public class TestModel:IValidatableObject
    {
        string MyDateTime{get;set;}

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            List<ValidationResult> v = new List<ValidationResult>();
            DateTime dt = default(DateTime);
            DateTime.TryParseExact(MyDateTime, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture,DateTimeStyles.None,out dt);
            if (dt.Equals(default(DateTime)))
                v.Add(new ValidationResult("Invalid Date time"));
            return v;
        }
    }

答案 3 :(得分:0)

还有一个,在ModelBinder中更改FormatException消息(但是远远地......)。

DefaultModelBinder.GetValueInvalidResource是静态方法。我无法覆盖此方法。因为我创建了CustomModelBinder类并重写了SetProperty方法。

[Required]
[AdditionalMetadata(
 "PropertyValueInvalid",
 "Wrong Syntax Entered, Needed:day/Month/Year Hour:Minutes:Seconds")]
public DateTime? Posted { get; set; }

创建自定义ModelBinder

public class CustomModelBinder : DefaultModelBinder
{
    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
    {
        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);

        var propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
        var invalidMessage = propertyMetadata.AdditionalValues.ContainsKey("PropertyValueInvalid")
                                 ? (string)propertyMetadata.AdditionalValues["PropertyValueInvalid"]
                                 : string.Empty;
        if (string.IsNullOrEmpty(invalidMessage))
        {
            return;
        }

        // code from DefaultModelBinder
        string fullPropertyKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
        if (!bindingContext.ValueProvider.ContainsPrefix(fullPropertyKey))
        {
            return;
        }
        ModelState modelState = bindingContext.ModelState[fullPropertyKey];
        foreach (ModelError error in modelState.Errors.Where(err => String.IsNullOrEmpty(err.ErrorMessage) && err.Exception != null).ToList())
        {
            for (Exception exception = error.Exception; exception != null; exception = exception.InnerException)
            {
                if (exception is FormatException)
                {
                    string displayName = propertyMetadata.GetDisplayName();
                    string errorMessageTemplate = invalidMessage;
                    string errorMessage = String.Format(CultureInfo.CurrentCulture, errorMessageTemplate,
                                                        modelState.Value.AttemptedValue, displayName);
                    modelState.Errors.Remove(error);
                    modelState.Errors.Add(errorMessage);
                    break;
                }
            }
        }
    }
}

这个怎么样?