i have ASP.NET Web API project
i want to store my date using 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 create 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 send my POST request using Fiddler
but in debug break point birthDate of my Person class set to null what is wrong? how can i send my date in persian format??
1 Answers
Answers 1
The DateOfBirth
in your model POCO should not be of type PersianCalendar
. A calendar is used to manipulate DateTime
objects, not as a container of DateTime
objects.
Your model should store the date of birth as a normal DateTime
, then you can use a PersianCalendar
to manipulate it. The easy (but a bit ugly) way to do this is to have a DateTime
field and a separate public string
property for getting and setting the date as formatted by 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 general specific moment in time. It does not have any uniquely correct string representation. But if you use something like what I have above, then you are kind of deciding that for your application the only correct string representation is a Persian date, formatted as yyyy/MM/dd
.
EDIT: You can also create a custom JSON JsonConverter
and use that in your model. Your POCO model could then 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
is not well tested for edge cases. Seems to work ok as long as the data it is manipulating is valid though.
0 comments:
Post a Comment