Resolved CustomValidationAttribute doesn't work

Dragon4ik

Member
Joined
Oct 24, 2020
Messages
16
Programming Experience
Beginner
Hi. everyone!
Actually this question is the continuation of Question, but now I have the same problem on ASP.Net MVC
I have the following task : write the validation attribute, which checks, if String format is right to parse into DateTimeOffset and if it isn't, app should throw an Exception. I try to get solution from StackOverflow, but it doesn't work and I can't get why.

MyCustomAttribute code:
C#:
 public class DateStringAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string date = value.ToString();
            var format = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzzz";
            IFormatProvider provider = CultureInfo.InvariantCulture.DateTimeFormat;

            DateTimeOffset startDate;

            if (!DateTimeOffset.TryParseExact(date, format, provider, DateTimeStyles.AllowWhiteSpaces, out startDate))
            {
                throw new Exception("Something went wrong");
            }


            return ValidationResult.Success;
        }
    }

Model code:
C#:
public class EventModel
    {
        [DateString]
        public string Date { get; set; }
    }

Controller code:
C#:
 public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            EventModel eventModel = new EventModel { Date = "Fri Aug 30 2014 00:00:00 GMT+0300" };
            return Content($"{eventModel.Date}");
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }

I see that is a simple problem, but can somebody explain me why it doesn't work and how to make it to work?
Thank you for any help!!!
 
Solution
I haven't inherited ValidationAttribute for some time but I'm fairly certain that the issue is the fact that you're throwing an exception when you shouldn't be. That method is supposed to return whether the input is valid or not. If it's not then you return an appropriate error message, e.g.
C#:
if (DateTimeOffset.TryParseExact(date, format, provider, DateTimeStyles.AllowWhiteSpaces, out startDate))
{
    return ValidationResult.Success;
}

return new ValidationResult("The input string was not in the correct format.")
Another option would be call ParseExact instead and return the error message that it produces:
C#:
try
{
    _ = DateTimeOffset.ParseExact(date, format, provider, DateTimeStyles.AllowWhiteSpaces);

    return...
You need to provide a FULL and CLEAR explanation of the problem, which includes what you're trying to achieve (check), how you're trying to achieve it (check) and what happens when you try (NOT check). You need to debug your code and explain EXACTLY how and where the actual behaviour differs from your expectation. "It doesn't work" is not an explanation. It means that you have only looked at the end result and not the steps to get to that result. You need to run the project and watch the code as it executes to see that it follows the path you expect and that each line does what you you expect. If you do that then you might even be able to fix the issue for yourself. If not, at least you can provide us with all the relevant information. If you don't know how to debug with breakpoints, etc, then stop what you're doing and learn now, then come back to this project and use what you have learned.
 
You need to provide a FULL and CLEAR explanation of the problem, which includes what you're trying to achieve (check), how you're trying to achieve it (check) and what happens when you try (NOT check). You need to debug your code and explain EXACTLY how and where the actual behaviour differs from your expectation. "It doesn't work" is not an explanation. It means that you have only looked at the end result and not the steps to get to that result. You need to run the project and watch the code as it executes to see that it follows the path you expect and that each line does what you you expect. If you do that then you might even be able to fix the issue for yourself. If not, at least you can provide us with all the relevant information. If you don't know how to debug with breakpoints, etc, then stop what you're doing and learn now, then come back to this project and use what you have learned.
The following String format Fri Aug 30 2014 00:00:00 GMT+0300 isn't right and isn't supposed to be valid to parse. So when I try to initialize a variable with this value, I expect that exception would be thrown, but instead of it my app works properly and return the string without any problem, not even reaching the row, where I throw an exception. That is the main problem.
зображення_2021-01-27_113757.png

That's why I think MyCustomAttribute doesn't work and I can't get why it is ignored.
 
So when you debugged your code, i.e. set a breakpoint and stepped through it line by line. Which line of code behaved differently to what you expected and how? Also, EXACTLY what data was in use at the time? This is what I told you do in my previous post: debug the code and provide all the relevant details.
 
The following String format Fri Aug 30 2014 00:00:00 GMT+0300 isn't right and isn't supposed to be valid to parse.
Really? You have this:
C#:
var format = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzzz";
Why would "Fri Aug 30 2014 00:00:00 GMT+0300" not be valid against that format? I haven't checked the documentation specifically but it looks pretty good to me.
 
Really? You have this:
C#:
var format = "ddd MMM dd yyyy HH:mm:ss 'GMT'zzzz";
Why would "Fri Aug 30 2014 00:00:00 GMT+0300" not be valid against that format? I haven't checked the documentation specifically but it looks pretty good to me.
Because this value wouldn't be parsed. The valid string is "Sat Aug 30 2014 00:00:00 GMT+0300"
 
So when you debugged your code, i.e. set a breakpoint and stepped through it line by line. Which line of code behaved differently to what you expected and how? Also, EXACTLY what data was in use at the time? This is what I told you do in my previous post: debug the code and provide all the relevant details.
I expect that exception would be thrown when I try to return not appropriate value in Index action, but it doesn't. And what I expect the ExceptionThrown message in output, but not the string, which I show on image in previous post.
 
Because this value wouldn't be parsed. The valid string is "Sat Aug 30 2014 00:00:00 GMT+0300"
See, this is exactly why you need to explain the issue at the outset. Why would you assume that we would know what day of the week it was on a particular date in 2014? You've wasted our time by not explaining yourself properly until I prompted you twice to do so. Please learn the lesson and provide ALL the relevant information at the outset in future.
 
Last edited:
Also, I haven't inherited

See, this is exactly why you need to explain the issue at the outset. Why would you assume that we would know what day of the week it was on a particular date in 2014? You've wasted our time by not explaining yourself properly until I prompted you twice to do so. Please learn the lesson and provide ALL the relevant information at the outset in future.
My fault, sorry. But can you say me why it doesn't work as I expect?
 
I haven't inherited ValidationAttribute for some time but I'm fairly certain that the issue is the fact that you're throwing an exception when you shouldn't be. That method is supposed to return whether the input is valid or not. If it's not then you return an appropriate error message, e.g.
C#:
if (DateTimeOffset.TryParseExact(date, format, provider, DateTimeStyles.AllowWhiteSpaces, out startDate))
{
    return ValidationResult.Success;
}

return new ValidationResult("The input string was not in the correct format.")
Another option would be call ParseExact instead and return the error message that it produces:
C#:
try
{
    _ = DateTimeOffset.ParseExact(date, format, provider, DateTimeStyles.AllowWhiteSpaces);

    return ValidationResult.Success;
}
catch (Exception e)
{
    return new ValidationResult(e.Message);
}
 
Solution
Back
Top Bottom