1

I have a MVC core project with EF core data context. I've used scaffolding to create CRUD. I just want to know is there anyway to use my custom logic for parsing datetime in text box when the user hit save?

Currently I have this in Create page:

<div class="form-group col-md-6 col-xs-12">
    <label asp-for="Lead.BDayDateTime" class="control-label"></label>
    <input asp-for="Lead.BDayDateTime" class="form-control" />
    <span asp-validation-for="Lead.BDayDateTime" class="text-danger"></span>
</div>

and its the definition in my model:

[Required(ErrorMessage = "Please enter year of birth or birthday (ex. 1363, 1984, 1984-09-23, 1363-07-01)")]
[Display(Name = "Birthday", Prompt = "Birth Year or Birthday", Description = "Please enter year of birth or birthday (ex. 1363, 1984, 1984-09-23, 1363-07-01)")]
[DisplayFormat(NullDisplayText = "Not Entered", DataFormatString = "{0:yyyy}", ApplyFormatInEditMode = true)]
public DateTime BDayDateTime { get; set; }

I want to manually parse datetime, so the user can enter non-Gregorian datetime values (and I'll convert them to Gregorian before saving to database).

Shahab
  • 794
  • 2
  • 12
  • 23

2 Answers2

0

I found a solution to parse my custom date string to DateTime using TypeConverter:

I created a custom TypeConverter:

public class JalaliAwareDateConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context,
        Type sourceType)
    {
        if (sourceType == typeof(string))
            return true;
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string s)
        {
            return s.ParseDateString(); // My custom parser
        }

        return base.ConvertFrom(context, culture, value);
    }
}

and registered it in Startup.cs (Based on my experience and thanks to this answer and @zdeněk comment, TypeConverter attribute do not work in asp.net core):

TypeDescriptor.AddAttributes(typeof(DateTime), new TypeConverterAttribute(typeof(JalaliAwareDateConverter)));

Now, I have valid value in DateTime property, but the validation still fails. This problem was because of Regular Expression validator which was trying to validate DateTime object! Removed the regex validator and voila, it works!

Shahab
  • 794
  • 2
  • 12
  • 23
-1

If you want to define custom validation logic, you need to create a custom class that derives from ValidationAttribute

Example code:

using System.ComponentModel.DataAnnotations;

namespace StatisticsWeb.Models
{
    public class PatientFormBirthdayValidation : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var patient = (Patient)validationContext.ObjectInstance;
            if (patient.BirthDate == null)
            {
                return new ValidationResult("Date of Birth field is required");
            }
            else if ((patient.BirthDate >= DateTime.Now) || (patient.BirthDate < DateTime.MinValue))
            {
                return new ValidationResult("Date of Birth is invalid");
            }
            else
            {
                return ValidationResult.Success;
            }
        }
    }
}

And decorate your model with this attribute:

[PatientFormBirthdayValidation]
public DateTime BDayDateTime { get; set; }

Of course you can use other attributes, like [Display(Name = "Date of Birth")] and [Required]

mirushaki
  • 897
  • 1
  • 10
  • 13
  • This is not what I am looking for. I actually want to change the value using my custom parser. I dont want to just validate the value. – Shahab Oct 16 '18 at 17:52