我有一个控制器动作,它有效地简单地返回模型的JsonResult。所以,在我的方法中,我有如下内容:

return new JsonResult(myModel);

这很有效,除了一个问题。在模型中有一个日期属性,这似乎在Json结果中返回,如下所示:

"\/Date(1239018869048)\/"

我应该如何处理日期,以便它们以我所需的格式返回?或者我如何处理脚本上面的这种格式?


当前回答

我一直在研究这个问题的解决方案,因为上面的答案都没有真正帮助到我。我正在使用jquery周日历,需要我的日期在服务器和本地页面上有时区信息。经过一番深入研究,我想出了一个可能会帮助到其他人的解决方案。

我使用asp.net 3.5, vs 2008, asp.net MVC 2,和jquery周日历,

首先,我使用Steven Levithan编写的一个库,它有助于处理客户端上的日期,Steven Levithan的日期库。isoUtcDateTime格式非常适合我所需要的。在我的jquery AJAX调用中,我使用isoUtcDateTime格式库提供的格式函数,当AJAX调用命中我的动作方法时,datetime Kind被设置为本地并反映服务器时间。

当我通过AJAX发送日期到我的页面时,我通过使用“ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz”格式化日期将它们作为文本字符串发送。这种格式在客户端使用时很容易转换

var myDate = new Date(myReceivedDate);

以下是我的完整解决方案,减去Steve Levithan的源代码,你可以下载:

控制器:

public class HomeController : Controller
{
    public const string DATE_FORMAT = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz";

    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }


    public JsonResult GetData()
    {
        DateTime myDate = DateTime.Now.ToLocalTime();

        return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
    }

    public JsonResult ReceiveData(DateTime myDate)
    {
        return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
    }
}

Javascript:

<script type="text/javascript">

function getData() {
    $.ajax({
        url: "/Home/GetData",
        type: "POST",
        cache: "false",
        dataType: "json",
        success: function(data) {
            alert(data.myDate);
            var newDate = cleanDate(data.myDate);
            alert(newDate);
            sendData(newDate);
        }
    });
} 

function cleanDate(d) {
    if (typeof d == 'string') {
        return new Date(d) || Date.parse(d) || new Date(parseInt(d));
    }
    if (typeof d == 'number') {
        return new Date(d);
    }
    return d;
}

function sendData(newDate) {
    $.ajax({
        url: "/Home/ReceiveData",
        type: "POST",
        cache: "false",
        dataType: "json",
        data:
        {
            myDate: newDate.format("isoUtcDateTime")
        },
        success: function(data) {
            alert(data.myDate);
            var newDate = cleanDate(data.myDate);
            alert(newDate);
        }
    });
}

// bind myButton click event to call getData
$(document).ready(function() {
    $('input#myButton').bind('click', getData);
});
</script>

我希望这个简单的例子能帮助那些和我处境相同的人。在这个时候,它似乎工作得很好与微软JSON序列化和保持我的日期跨时区正确。

其他回答

这不是最优雅的方式,但对我来说很管用:

var ms = date.substring(6, date.length - 2);
var newDate = formatDate(ms);


function formatDate(ms) {

    var date = new Date(parseInt(ms));
    var hour = date.getHours();
    var mins = date.getMinutes() + '';
    var time = "AM";

    // find time 
    if (hour >= 12) {
        time = "PM";
    }
    // fix hours format
    if (hour > 12) {
        hour -= 12;
    }
    else if (hour == 0) {
        hour = 12;
    }
    // fix minutes format
    if (mins.length == 1) {
        mins = "0" + mins;
    }
    // return formatted date time string
    return date.getMonth() + 1 + "/" + date.getDate() + "/" + date.getFullYear() + " " + hour + ":" + mins + " " + time;
}

客户端有很多解决方案,但是如果您愿意,可以更改输出服务器端。

有一些方法可以解决这个问题,我将从基本的开始。您必须创建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

不是没有原因,而是还有别的办法。首先,构造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") };

我不得不说,额外的步骤很烦人,但效果很好。

js是一个扩展的datetime库,它也支持这个功能。http://momentjs.com/docs/#/parsing/asp-net-json-dates/

ex - Date(1198908717056-0700):时刻(“”)

这可能会有帮助。恰好输出

下面是我的Javascript解决方案——非常像JPot,但更短(可能更快一点):

value = new Date(parseInt(value.substr(6)));

"value.substr(6)"去掉"/Date("部分,parseInt函数忽略出现在结尾的非数字字符。

编辑:我故意省略了基数(parseInt的第二个参数);请看我下面的评论。另外,请注意ISO-8601日期比这种旧格式更受欢迎——因此这种格式通常不应该用于新的开发。

对于ISO-8601格式的JSON日期,只需将字符串传递给Date构造函数:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support