【问题标题】:Correct way to use PersianCalendar as Table column in entity framework在实体框架中使用 PersianCalendar 作为表列的正确方法
【发布时间】:2017-01-31 07:25:19
【问题描述】:

我有一个 ASP.NET Web API 项目,我试图在其中使用波斯日历存储我的日期。这是我的 POCO 课程。

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; }


}   

我为我的 API 创建了一个 POST 方法。

 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);
        }
    }  

我正在使用 Fiddler 发送我的 POST 请求。

但在 Chrome 开发工具中,我的 Person 类的断点birthDate 设置为 null。 谁能帮我解决问题? 如何以波斯格式发送我的日期??

【问题讨论】:

  • 在下面的回答中添加了不同的方式。

标签: asp.net asp.net-web-api2


【解决方案1】:

模型 POCO 中的 DateOfBirth 不应该是 PersianCalendar 类型。日历用于操作DateTime 对象,而不是作为DateTime 对象的容器。

您的模型应该将出生日期存储为普通的DateTime,然后您可以使用PersianCalendar 对其进行操作。执行此操作的简单(但有点难看)方法是拥有一个 DateTime 字段和一个单独的公共 string 属性,用于获取和设置波斯日历格式的日期:

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);
        }
    }
}

请记住,DateTime 代表一般的特定时刻。它没有任何唯一正确的字符串表示。但是,如果您使用类似于我上面的内容,那么您有点决定对于您的应用程序,唯一正确的字符串表示是波斯日期,格式为yyyy/MM/dd


编辑:您还可以创建自定义 JSON JsonConverter 并在您的模型中使用它。您的 POCO 模型可能如下所示:

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;
}

PersianDateConverter 类看起来像这样:

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;
    }
}

注意:这个PersianDateConverter 没有很好地测试边缘情况。只要它正在操作的数据是有效的,似乎就可以正常工作。

【讨论】:

  • tnx 用于重播,但有没有更好的方法将此日期存储为 DateTime 而不是 String?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多