0

I've made a simple web application and it's work correctly on local db. After publishing, there is an error connected with DateTime:

System.FormatException: String was not recognized as a valid DateTime.

The code in ViewModel looks like this:

[Required]
[ValidTime]
[Display(Name = "Game time")]
public string Time { get; set; }
[Required]
[FutureDate]
[Display(Name = "Game date")]
public string Date { get; set; }
public DateTime GetDateTime()
{
    return DateTime.Parse(string.Format("{0} {1}", Date, Time));          
}

Controller code:

public ActionResult Create(GameFormViewModel viewModel)
{
    if (!ModelState.IsValid)
        return View("GameForm", viewModel);
    var userId = User.Identity.GetUserId();
    var game = new Game
    {
        TeamA = viewModel.TeamA,
        TeamB = viewModel.TeamB,
        DateTime = viewModel.GetDateTime(),
        LeagueId = viewModel.Id,
        AdminId = userId

    };

    _context.Games.Add(game);
    _context.SaveChanges();


    return RedirectToAction("MyLeagues", "Leagues");
}

Why it's work at local db and why there is an error after publishing ?

Update: Thats my FutureDate class

public class FutureDate : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        DateTime datetime;
        var isvalid = DateTime.TryParseExact(Convert.ToString(value),
            "dd-mm-yyyy",
            CultureInfo.CurrentCulture,
            DateTimeStyles.None,
            out datetime);



        return (isvalid && datetime >= DateTime.Now.AddDays(-1));

    }
}
3
  • Can you set a breakpoint in line DateTime = viewModel.GetDateTime(),, and also add a watcher to viewModel to check the values, better yet, post the screenshot... Commented Jul 25, 2017 at 15:43
  • 3
    @Jakubb, probably the source of the problem is the different locales on your local workstation and on server. Commented Jul 25, 2017 at 15:51
  • Also could be the format of the date via input and the format of the date expected by the Parse method. What format of date and time are you entering in the UI? Are you entering time as military time or 3:45 PM format? Commented Jul 25, 2017 at 15:52

1 Answer 1

2

The error probably has something to do with your custom validation attributes (ValidTime or FutureDate). There's no other code here that might potentially generate that exception.

However, the way you're going about this bad in the first place, and if you simply do it the right way, this won't even be an issue. You'll also have less bugs in general, as right now, if an invalid date/time value is posted, your whole app is going to explode.

Change the properties on your view model to:

[Required]
[Display(Name = "Game time")]
[DataType(DataType.Time)]
public TimeSpan? Time { get; set; }

[Required]
[FutureDate]
[Display(Name = "Game date")]
[DataType(DataType.Date)]
public DateTime? Date { get; set; }

Then, your GetDateTime method simply becomes:

public DateTime GetDateTime()
{
    return Date.HasValue && Time.HasValue ? Date.Add(Time) : default(DateTime);
}

By making the Time and Date properties a TimeSpan and DateTime, respectively, the modelbinder will handle the conversion from the posted string values. If either cannot be converted to their respective types, the default value (null) will be filled instead, which will then trigger your Required validation. Your GetDateTime method, now doesn't have to parse anything; it just adds the two together if they have a value.

Sign up to request clarification or add additional context in comments.

3 Comments

Chris, thank you for help but something still doesn't work. I've got error at "Date.Add(Time)" - "'DateTime?' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'DateTime?' could be found..." so i added Value to Date and time "Date.Value.Add(Time.Value)". Now i can't add any date in my form. Ther's always error probably connected with futuredate.
public class FutureDate : ValidationAttribute { public override bool IsValid(object value) { DateTime dateTime; var isValid = DateTime.TryParseExact(Convert.ToString(value), "dd-MM-yyyy", CultureInfo.CurrentCulture, DateTimeStyles.None, out dateTime); return (isValid && dateTime >= DateTime.Now.AddDays(-1)); } }
I've added futuredate class to first post

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.