1

I have a metadata class for my Customer where I validate the PurchaseDate.

  • The first annotation (DataType) is for formatting the date in an EditorFor, to show just the date part.
  • The second annotation is a custom validation to verify that the value is a DateTime, including a custom error message.

My problem is that the first annotation will cancel out the errormessage of the second annotation.

Is it possible to combine these two using only data annotations? Or do I have to format the date in the EditorFor?

[MetadataType(typeof(Customer_Metadata))]
public partial class Customer { }

public class Customer_Metadata
{
    [DataType(DataType.Date)]
    [MyDate(ErrorMessage = "Invalid purchase date")]
    public DateTime? PurchaseDate { get; set; }
}

The same problem occurs if I try to replace the [DataType(DataType.Date)] with

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

I won't get my custom error message.

EDIT
My main goal is to have a custom error message while also only showing the date part in the rendered input field. Is it possible with only data annotations?

Here's the MyDate attribute:

public class MyDate : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        DateTime dt;
        var test = DateTime.TryParse((value ?? string.Empty).ToString(), out dt);
        if (test)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(ErrorMessage);
        }
    }
}
Niklas
  • 13,005
  • 23
  • 79
  • 119
  • How is `MyDate` attribute defined? – Mihail Stancescu Feb 11 '16 at 19:06
  • `[DataType(DataType.Date)]` is not a validation attribute. Its purpose is to add the `type="Date"` attribute when using `EditorFor()` which will render the browsers implementation of a HTML5 datepicker (which is supported only in Chrome and Edge). `[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]` ensures the format is correct when using the HTML5 datepicker because the date string must be in ISO format. They must be used together. –  Feb 11 '16 at 22:36
  • What is your custom `MyDate` attribute? Since your property is `DateTime` then the value will always be validated as a date anyway so its unclear what your trying to do. If you want a custom error message for the type, then you can create a resource file that overrides the default. –  Feb 11 '16 at 22:39
  • @StephenMuecke Good information here Stephen. Sounds like I need to read up more on this. I've update my question with the `MyDate` definition and what I want to achieve. – Niklas Feb 12 '16 at 09:06
  • There is really no need for that attribute at all. Its only repeating what the `DefaultModelBinder already does. What I assume you mean is that if you you enter a value which is not a valid date, you get the default error message. You can change that by using a resource file as per [this answer](http://stackoverflow.com/questions/6214066/how-to-change-default-validation-error-message-in-asp-net-mvc). If so, let me know and I'll mark it as a dupe. –  Feb 12 '16 at 09:10
  • @StephenMuecke Maybe I'm wrong in thinking that attributes should be used to handle formatting? Should I just move the formatting of the PurchaseDate to the view or viewmodel? – Niklas Feb 12 '16 at 09:11
  • Using `[DisplayFormat]` is correct for formatting, and if your using the HTML5 datepicker (I don't recommend it because of the limited browser support) then its necessary to use it if using the `EditorFor()` method. The problem is that if in another view you use `@DisplayFor()` its going to be displayed as `yyy-MMM-dd` which you may not want –  Feb 12 '16 at 09:16
  • My preference is to use `[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] (or what ever format you want for display, and then for editing use `@Html.TextBoxFor(m =>m.Date, "{0:yyyy-MM-dd}", new { type="date" })` to generate the HTML5 datepicker –  Feb 12 '16 at 09:17
  • @StephenMuecke The `[DisplayFormat]` works fine. The `[MyDate]` custom validation and error message also works fine. It's when I combine these two that I don't get the custom error message. I guess overriding the default error message with a resource file is good as a last resort. Thank you for your input! – Niklas Feb 12 '16 at 09:27
  • That does not really make sense. The `[DisplayFormat]` attribute only determines how the value of formatted in the view (the html that's created) and is only applied when the view is sent to the browser (during this process the `MyDate` validation attribute is never called. But when you submit back to the server the validation attribute is call but the display attribute is not. There must be something else going on. When I get a chance I'll test your code and see if I can duplicate your issue. –  Feb 12 '16 at 10:40
  • @StephenMuecke - Did you ever get a chance to reproduce this? Otherwise I'm just gonna work around it and delete this question. – Niklas Mar 02 '16 at 12:56
  • Yes, I did try it, but I could not reproduce your problem at all (and was not able to work how you could have been getting the issue you were - I assume I must be dues to something you have not shown) –  Mar 02 '16 at 23:00
  • Mm, that's probably true. If I ever encounter it again I might ask another question, but I'll delete this one for now. Thank you for your support though =) – Niklas Mar 03 '16 at 08:46

0 Answers0