【问题标题】:Parsing a JSON date info into a C# DateTime将 JSON 日期信息解析为 C# DateTime
【发布时间】:2011-02-11 13:51:38
【问题描述】:

我有一个返回 CLR 对象的 WCF 服务。该对象定义如下:

[DataContract]
public class Person
{
  [DataMember]
  public string FullName
  {
    get { return fullName; }
    set { id = fullName; }
  }
  private string fullName = string.Empty;

  [DataMember]
  public DateTime BirthDate
  {
    get { return birthDate; }
    set { birthDate = value; }
  }
}

正在创建此对象的实例并从我的 WCF 服务返回。该服务如下所示:

[OperationContract]
[WebGet(UriTemplate = "/GetPersonByID/{id}", ResponseFormat = WebMessageFormat.Json)]
public Person GetPersonByID(string id)
{
  Person person = FindPersonByID(id);
  return person;
}

当我在我的应用程序中获得响应时,我可以成功提取 FullName 值。但是,我无法在客户端应用程序中成功地将 BirthDate 转换为 C# DateTime 对象。当转换为字符串时,BirthDate 看起来像这样:

\/Date(1297367252340-0500)\/

如何将它放入 C# DateTime 实例中?

谢谢!

【问题讨论】:

  • 没有 JSON 日期这样的东西。

标签: c# wcf json


【解决方案1】:

这里有两个选项:

您可以使用来自System.Web.Script.Serialization.JavaScriptSerializer(在 System.Web.Extensions.dll 中)的反序列化方法。

或者您可以使用 System.Runtime.Serialization.Json.DataContractJsonSerializer 中的 ReadObject 方法(在 System.Runtime.Serialization.dll 中或在 .NET 3.5 中的 System.ServiceModel.Web.dll 中)。

确保您的日期用引号括起来,例如:

string dateString = @"""\/Date(1297367252340-0500)\/""";

【讨论】:

  • 问题是,我的客户端是一个 Silverlight 应用程序。 Silverlight 没有反序列化方法。
  • 你想试试 DataContractJsonSerializer 吗?文档声称它在 Silverlight 3 和 4 中可用。
【解决方案2】:

日期采用这种奇怪格式的原因是 DateTime 是 WCF 中的一个原语。不幸的是,在 JSON 中序列化日期和时间没有通用的标准化格式——各种框架使用各种字符串格式。

难题在于,WCF 需要在本机上了解通过网络传输的特定字符串确实是 DateTime,而不仅仅是另一个普通的 JSON 字符串。因此奇怪的格式。一旦 DataContractJsonSerializer 遇到以 \/Date 开头的日期,它就会开始尝试将其解析为日期。

现在,回答您的问题,当您通过网络发送 DateTime 时,这取决于您使用的是 Web 浏览器客户端、Silverlight 客户端还是 WCF 客户端。

WCF 客户端或 Silverlight 2+ 客户端不应该有这个问题 - 他们应该自动使用 DataContractJsoNSerializer,如果他们不使用它,您可以手动插入 DCJS。

如果您使用的是 Web 客户端,则可以包含 ASP 附带的 .js 文件。 NET AJAX(我相信它被称为 MicrosoftAspNetAjax.js 或 MicrosoftAjax.cs,尽管名称可能已更改)。它的反序列化函数也会自动解析这些日期。

希望有帮助!

【讨论】:

  • 一个比简单地说没有 JSON 日期这样的东西更有用和信息丰富的答案。
【解决方案3】:

好吧,最近我不得不在一个 Android Mobile (Xamarin Studio) 应用程序项目上工作,由于部署到此特定设备版本(Android API 16 版本 4.2)期间引发的错误,我无法使用 Newtonsoft Json (Json.NET) .1).

幸运的是,我找到了 json (System.Json) 的替代库。然而,这个库没有办法将 JSON 日期隐式转换为 C# DateTime。

我创建了以下两个函数,用于从字符串 json 日期(即 /Date(1389435240000+0000)/) 进行可空日期和日期转换

代码可以改进,但现在可以完成工作

public static DateTime? ConvertToNallableDate(string date)
        {

            DateTime? val = null;
            /*          /Date(1389435240000+0000)/*/
            try{
                if(!string.IsNullOrEmpty(date))
                {
                    date = date.Replace ("/Date(", string.Empty).Replace (")/", string.Empty);
                    int pIndex = date.IndexOf ("+");
                    if(pIndex < 0) pIndex = date.IndexOf("-");
                    long millisec = 0;
                    date = date.Remove (pIndex);
                    long.TryParse (date, out millisec);
                    System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
                    DateTime newDate = DateTime.Parse ("1970,1,1", ci);
                    newDate = newDate.AddMilliseconds(millisec);
                    val = newDate == null ? (DateTime?)null : newDate;

                }
            }catch {
                val = null;
            }
            return val;
        }

        public static DateTime ConvertToDate(string date)
        {

            DateTime val = new DateTime();
            /*/Date(1389435240000+0000)/*/
            try{
            if(!string.IsNullOrEmpty(date))
            {
                date = date.Replace ("/Date(", string.Empty).Replace (")/", string.Empty);
                int pIndex = date.IndexOf ("+");
                if(pIndex < 0) pIndex = date.IndexOf("-");
                long millisec = 0;
                date = date.Remove (pIndex);
                long.TryParse (date, out millisec);
                System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
                DateTime newDate = DateTime.Parse ("1970,1,1", ci);
                val = newDate.AddMilliseconds(millisec);

            }
            }catch {
                val = new DateTime();
            }
            return val;
        }

【讨论】:

  • 如果 json 日期中没有时区后缀则中断
【解决方案4】:

这解决了我的问题

using System.Web.Script.Serialization;


//code
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
DateTime ddate = json_serializer.Deserialize<DateTime>(@"""\/Date(1326038400000)\/""").ToLocalTime();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多