我有一个控制器动作,它有效地简单地返回模型的JsonResult。所以,在我的方法中,我有如下内容:
return new JsonResult(myModel);
这很有效,除了一个问题。在模型中有一个日期属性,这似乎在Json结果中返回,如下所示:
"\/Date(1239018869048)\/"
我应该如何处理日期,以便它们以我所需的格式返回?或者我如何处理脚本上面的这种格式?
我有一个控制器动作,它有效地简单地返回模型的JsonResult。所以,在我的方法中,我有如下内容:
return new JsonResult(myModel);
这很有效,除了一个问题。在模型中有一个日期属性,这似乎在Json结果中返回,如下所示:
"\/Date(1239018869048)\/"
我应该如何处理日期,以便它们以我所需的格式返回?或者我如何处理脚本上面的这种格式?
当前回答
我发现这是更改服务器端的最简单的方法。
using System.Collections.Generic;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace Website
{
/// <summary>
/// This is like MVC5's JsonResult but it uses CamelCase and date formatting.
/// </summary>
public class MyJsonResult : ContentResult
{
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter> { new StringEnumConverter() }
};
public FindersJsonResult(object obj)
{
this.Content = JsonConvert.SerializeObject(obj, Settings);
this.ContentType = "application/json";
}
}
}
其他回答
请看这个帖子:
http://forums.asp.net/p/1038457/1441866.aspx#1441866
基本上,虽然Date()格式是有效的javascript,但它不是有效的JSON(有区别)。如果您想要使用旧格式,您可能必须自己创建一个外观并转换值,或者找到一种方法来获取JsonResult中类型的序列化器,并让它使用日期的自定义格式。
不是没有原因,而是还有别的办法。首先,构造LINQ查询。然后,构造枚举结果的查询,并应用适合您的格式类型。
var query = from t in db.Table select new { t.DateField };
var result = from c in query.AsEnumerable() select new { c.DateField.toString("dd MMM yyy") };
我不得不说,额外的步骤很烦人,但效果很好。
客户端有很多解决方案,但是如果您愿意,可以更改输出服务器端。
有一些方法可以解决这个问题,我将从基本的开始。您必须创建JsonResult类的子类,并重写ExecuteResult方法。在此基础上,您可以采用几种不同的方法来更改序列化。
方法1: 默认实现使用JsonScriptSerializer。如果查看文档,可以使用RegisterConverters方法添加自定义JavaScriptConverters。但是有一些问题:JavaScriptConverter序列化到一个字典,也就是它接受一个对象并序列化到一个Json字典。为了使对象序列化为字符串,它需要一点技巧,请参阅post。这个特殊的hack也将转义字符串。
public class CustomJsonResult : JsonResult
{
private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
// Use your custom JavaScriptConverter subclass here.
serializer.RegisterConverters(new JavascriptConverter[] { new CustomConverter });
response.Write(serializer.Serialize(Data));
}
}
}
方法二(推荐): 第二种方法是从重写的JsonResult开始,然后使用另一个Json序列化器,在我的例子中是Json。净序列化器。这并不需要方法1的技巧。这是我的JsonResult子类的实现:
public class CustomJsonResult : JsonResult
{
private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
// Using Json.NET serializer
var isoConvert = new IsoDateTimeConverter();
isoConvert.DateTimeFormat = _dateFormat;
response.Write(JsonConvert.SerializeObject(Data, isoConvert));
}
}
}
使用的例子:
[HttpGet]
public ActionResult Index() {
return new CustomJsonResult { Data = new { users=db.Users.ToList(); } };
}
额外的学分: 詹姆斯Newton-King
在knockoutjs中处理日期的更好方法是使用moment库并像boss一样处理日期。您可以轻松地处理/Date(-62135578800000)/这样的日期。不需要担心如何在控制器中序列化日期。
function jsonToDate(date,format) {
return moment(date).format(format);
}
像这样使用它
var formattedDate = jsonToDate(date,'MM/DD/YYYY')
Momentjs支持大量的日期时间格式和日期实用函数。
很烦人,不是吗?
我的解决方案是改变我的WCF服务,让它以更可读(非微软)的格式返回DateTimes。请注意下面的“UpdateDateOriginal”,这是WCF的默认日期格式,以及我的“UpdateDate”,它被格式化为更易于阅读的格式。
以下是如何做到这一点:
更改WCF日期格式
希望这能有所帮助。