0

Im having some problems utilizing RegularExpression attribute in a ASP.net MVC project.

It seems to work client side, it goes away when it fits, however then upon post action, the model state is checked for being valid, it ends up posting error, that it must follow the regular expression.

I have tried theese following:

^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4} [0-9]{1,2}:[0-9]{1,2}$

^\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{1,2}$

Essentially it must catch 14/12/2014 14:20 as input.

Any ideas? I'm lost.

Model:

[Required]
[Display(Name = "TimeDisplay", ResourceType = typeof(Resources.Models.Log))]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
[RegularExpression(@"^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4} [0-9]{1,2}:[0-9]{1,2}$")]
public DateTime Time { get; set; }

Controller Action:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Log log)
{
    if (ModelState.IsValid)
    {
        db.Logs.Add(log);
        db.SaveChanges();
        TempData["Notification"] = AlertGenerator.GenerateAlert(AlertGenerator.Level.Success, "Success! Log Saved");
        return RedirectToAction("Index");
    }

    return View(log);
}
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Zaixu
  • 191
  • 1
  • 2
  • 8
  • With your regular expression, '00/00/0000 99:99' is a valid input. Are you sure you want that? It might be better to use a datepicker for the date component and dropdowns for the hour and minute components. – rikitikitik Apr 16 '14 at 00:23
  • Its for manual input, if people make an type error so be it, at the moment it is primarily for proper format of input so users know it, and not input something way wicked – Zaixu Apr 16 '14 at 00:29
  • [This answer](http://stackoverflow.com/questions/6388238/validate-a-date-in-a-specific-format-in-asp-net-mvc-3?rq=1) suggests a problem using `RegularExpression` validation with `DateTime`. And [this](http://stackoverflow.com/questions/1352948/how-to-get-all-errors-from-asp-net-mvc-modelstate) gives you a way to examine exactly what's wrong with your validation. Now if I drop the `RegularExpression` validation and reverse the date format to `{0:MM/dd/yyyy HH:mm}` my validation succeeds which suggests a culture or localization issue. – Jasen Apr 16 '14 at 02:14
  • Unfortunately DisplayFormat is just a way of showing the data, not a correction utility (iirc). If regularexpression is removed anything goes that datetime is able to parse, i use regularexpression to force users to fill date/time and not forget anything – Zaixu Apr 16 '14 at 11:18

1 Answers1

0

As I know, MVC will use current CultureInfo (on server) to parse DateTime format, so you cannot directly binding "dd/MM/yyyy HH:mm" to your entity.

My solution is creating ViewModel then use DateTime.ParseExact(...) to parse the date:

Model:

[Display(Name = "TimeDisplay", ResourceType = typeof(Resources.Models.Log))]
[Required]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:mm}")]
public DateTime Time { get; set; }

ViewModel

[Display(Name = "TimeDisplay", ResourceType = typeof(Resources.Models.Log))]
[Required]
public string Time { get; set; }

Controller

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(LogViewModel logViewModel)
{
    if (ModelState.IsValid)
    {
        // convert from ViewModel to Entity Model
        Log log = new Log(logViewModel);
        // parse the time
        log.Time = DateTime.ParseExact(logViewModel.Time, "dd/MM/yyyy HH:mm", null);

        db.Logs.Add(log);
        db.SaveChanges();
        TempData["Notification"] = AlertGenerator.GenerateAlert(AlertGenerator.Level.Success, "Success! Log Saved");
        return RedirectToAction("Index");
    }

    return View(log);
}
tdat00
  • 810
  • 1
  • 8
  • 11