The correct way to use a PersianCalendar column as a column in an entity structure

I have an ASP.NET Web API project in which I am trying to save my date using the Persian calendar. Here is my POCO class.

public class Person { PersianCalendar p = new PersianCalendar(); public Person() { } public Person(string firstName, string lastName, PersianCalendar birthDate) { FirstName = firstName; LastName = lastName; DateOfBirth = birthDate; } public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public PersianCalendar DateOfBirth { get; set; } } 

I created a POST method for my API.

  public HttpResponseMessage Post([FromBody] Person _p) { try { db.Persons.Add(_p); db.SaveChanges(); var msg = Request.CreateResponse(HttpStatusCode.Created, _p); msg.Headers.Location = new Uri(Request.RequestUri + _p.PersonId.ToString()); return msg; } catch(Exception ex) { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex); } } 

and I submit my POST request using Fiddler. enter image description here

but in Chrome Dev Tools, the BirthDate breakpoint of my Person class is null. enter image description here Can someone help me with what's wrong? How can I send my date in Persian format?

+7
asp.net-web-api2
source share
1 answer

DateOfBirth in your POCO model must not be of type PersianCalendar . The calendar is used to manage DateTime objects, not as a container of DateTime objects.

Your model should store the date of birth as a regular DateTime , then you can use PersianCalendar to manipulate it. An easy (but slightly ugly) way to do this is to have a DateTime field and a separate public string property to get and set the date formatted in the Persian calendar:

 public class Person { PersianCalendar p = new PersianCalendar(); public Person() { } public Person(string firstName, string lastName, DateTime birthDate) { FirstName = firstName; LastName = lastName; DateOfBirth = birthDate; } public Person(string firstName, string lastName, string birthDateString) { FirstName = firstName; LastName = lastName; DateOfBirthString = birthDateString; } public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime DateOfBirth; public string DateOfBirthString { get { return string.Format("{0}/{1}/{2}", p.GetYear(DateOfBirth), p.GetMonth(DateOfBirth), p.GetDayOfMonth(DateOfBirth)); } set { var parts = value.Split('/'); DateOfBirth = p.ToDateTime(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), 0, 0, 0, 0); } } } 

Keep in mind that a DateTime represents a generic particular moment in time. It does not have a uniquely correct string representation. But if you use something like the one I have above, then you think that for your application the only valid string representation is the Persian date formatted as yyyy/MM/dd .


EDIT . You can also create a custom JSON JsonConverter and use it in your model. Your POCO model might look like this:

 public class Person { public Person() { } public Person(string firstName, string lastName, DateTime birthDate) { FirstName = firstName; LastName = lastName; DateOfBirth = birthDate; } public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } [JsonConverter(typeof(PersianDateConverter))] public DateTime DateOfBirth; } 

And the PersianDateConverter class looks like this:

 public class PersianDateConverter : JsonConverter { PersianCalendar pc = new PersianCalendar(); public PersianDateConverter() { } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { string persianDateString = reader.Value as string; if (persianDateString == null) throw new ArgumentException("Error in PersionDateConverter.ReadJson: Got null string"); var parts = persianDateString.Split('/'); return pc.ToDateTime(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), 0, 0, 0, 0); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { DateTime d = (DateTime)value; string output = string.Format("{0}/{1}/{2}", pc.GetYear(d), pc.GetMonth(d), pc.GetDayOfMonth(d)); writer.WriteValue(output); } public override bool CanConvert(Type objectType) { if (objectType.Name == "DateTime") return true; return false; } } 

Note This PersianDateConverter not very well tested for edge cases. It seems to be working fine as long as the data it manages is valid.

+4
source share

All Articles