0

I have a client side validation which restricts user to enter the date only in a certain range which is 20 years back from now. This is working fine. But the problem is, when the user changes his browser time back to 1 year, then the browser allows to enter the date that is a range greater than 20 years from now. We are using MVC for this. We have 4 tabs where this validation should happen in 2nd form, but the server side call happens when we save all the forms in form and we call the server side in the last tab. How can I achieve this?

I have already added some validation in the server side which restricts the user from server side, but this happens in the last tab when user clicks submit. What I want is, when user clicks on Next button or at least immediately after the user enters the date value in the 2nd tab itself, I want this logic to be happened. The code that I tried is as below:

var enrolledVal = Convert.ToDateTime(model.enrolledValue);
var a = (today.Year * 100 + today.Month) * 100 + today.Day;
var b = (enrolledVal.Year * 100 + enrolledVal.Month) * 100 + enrolledVal.Day;
var enrolledYears = (a - b) / 10000;
if (enrolledYears > 20)
{
var error = new JsonErrorModel { ErrorCode = -1, ErrorMessage = "Enrolled Date Exceeded 20 years"};
return Json(error);
}
user2083386
  • 135
  • 3
  • 19
  • 2
    You might be over complicating this Datetime has a year property. You could just take the two years from the two dates and subtract them to determine if the years are greater than 20. https://learn.microsoft.com/en-us/dotnet/api/system.datetime.year?view=netframework-4.8 – Jake Steffen Jun 05 '19 at 15:24
  • If you want, you can add validation to the model itself. Might save you some time with writing validation tests? The link is for ASP.NET Core 2.2 but this concept has been in ASP.NET MVC for a pretty long time. https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.2 – KevinLamb Jun 05 '19 at 15:27
  • @jake steffen, thanks. But I need this logic to be executed at the 2nd tab(which is form). On the button click in this page which is 'Next', it simply saves the current form on the front end and it takes to next tab and doesn't do anything server-side apart from this. So what would be the best approach for this to put my logic over here? – user2083386 Jun 05 '19 at 15:36
  • @KevinLamb, thanks for your response. In this article, under "Custom attributes" I could see there is a year parameter being passed into that constructor. When I create a custom attribute class, how can I pass the dynamic value which user inputs? – user2083386 Jun 05 '19 at 16:17
  • Check out [this answer](https://stackoverflow.com/questions/17321948/is-there-a-rangeattribute-for-datetime) for something similar to your case. You can get the values in the model by simply binding the form to the model properties. Here's [a tutorial](https://blog.michaelckennedy.net/2012/01/20/building-asp-net-mvc-forms-with-razor/) if you're using razor. – KevinLamb Jun 05 '19 at 16:37

1 Answers1

1

I think this might help

Get the year for enrolled date:

var enrolledVal = Convert.ToDateTime(model.enrolledValue).Year;

Get the current year

var current = DateTime.Now.Year;

Find difference

var result = enrolledVal - current;
Jake Steffen
  • 415
  • 2
  • 11
  • thanks for your response. But even this logic, do I have to put it in cshtml file or do I have to put it in the submit button click logic? If submit button click logic, then this would again happen at the 4th tab. But I need this to be in the 2nd tab itself. Please don't mind if my question seems to be silly or too basic, I was pretty new and I am still learning :-) – user2083386 Jun 05 '19 at 15:33
  • I wrote this thinking it was going to run on the server side. If you are wanting to do the validation on the client side you could try something like this: https://stackoverflow.com/questions/4537900/how-to-restrict-date-range-of-a-jquery-datepicker-by-giving-two-dates – Jake Steffen Jun 05 '19 at 15:36
  • thanks for your quick response once again. What you think is correct. I want the input date to be validated against the server date in my scenario. We already have the below logic which checks the date range. `[MandatoryField, Display(Name = "Enroller Year"), DataType(DataType.Date), UIHint("Date"), DateRange(MaxDateString = "now", MinOffsetString = "-20Y")] public virtual DateTime? EnrolledYear { get; set; }` – user2083386 Jun 05 '19 at 15:49
  • It might be best to control what the user can input – Jake Steffen Jun 05 '19 at 15:51
  • this issue is happening when the user changes his system date/time to previous year. As application is taking the current browser time, the user is able to through from UI. So, to restricts this, we would like to validate with the server date. But the message we would like to display is right in the 2nd tab itself without waiting till last tab where he clicks on submit button. – user2083386 Jun 05 '19 at 16:02
  • So you are trying to display a message to the user, but the message is on a tab they are not looking at? – Jake Steffen Jun 05 '19 at 16:08
  • Yes, but I am not displaying the message, because I am not quite sure how to display my message in tab 2 by redirecting the user to tab 2 from tab 4 where the server side validation happens after the user clicks on submit here. – user2083386 Jun 05 '19 at 16:13
  • You could just display the message out side of the tab, I have used toastr.js quite a bit. https://github.com/CodeSeven/toastr – Jake Steffen Jun 05 '19 at 16:16