简体   繁体   English

在MVC 3应用程序中,如何进行DateTimes和TimeSpans的简单AJAX / JSON往返?

[英]In an MVC 3 Application, how do I do a simple AJAX/JSON round trip of DateTimes and TimeSpans?

Given a simple round tripping scenario, how can I return JSON data to a browser and then accept updates from the browser via JSON that ModelBinds to a type w/ 3 properties: Int32, DateTime, TimeSpan? 给定一个简单的循环跳转场景,如何将JSON数据返回到浏览器,然后通过JSON将浏览器接受更新,模型绑定到类型w / 3属性:Int32,DateTime,TimeSpan?

Server Code (Controller) 服务器代码(控制器)

    public class Product
    {
        public int Id { get; set; }
        public DateTime Start { get; set; }
        public TimeSpan Duration { get; set; }
    }

    [AcceptVerbs(HttpVerbs.Get)]
    public JsonResult data()
    {
        return Json(
           new Product {
               Id = 1, Start = DateTime.Now, 
               Duration = TimeSpan.FromMinutes(30)}
           , JsonRequestBehavior.AllowGet);
    }

    [HttpPost]
    public void data(Product product)
    {
        //product is not bound; modelbinder fails on DateTime and TimeSpan
        Console.WriteLine("Data: " + product);
    }

Errors from Immediate Window 即时窗口的错误

ModelState["Start"].Errors[0]
{System.Web.Mvc.ModelError}
    ErrorMessage: "The value '/Date(1302295231115)/' is not valid for Start."
    Exception: null

ModelState["Duration"].Errors[0]
{System.Web.Mvc.ModelError}
    ErrorMessage: "The Duration field is required."
    Exception: null

Client Code (getData and changeData are bound to 2 different buttons) 客户端代码(getData和changeData绑定到2个不同的按钮)

<script type='text/javascript'>
    var myData;
    function getData(event)
    {
        $.getJSON('/home/data', function (data)
        {
            myData=data;
            console.dir(data);                
        });
    }

    function changeData(event)
    {
        var postData = JSON.stringify(myData);

        $.ajax({
            url: '/home/data',
            type: "POST",
            data: postData,
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function () {
                console.log('success!');
            },
            error: function () {
                console.log('fail!');
            }
            });
    }

    $(document).ready(function ()
    {
        $('#get').click(getData);
        $('#post').click(changeData);
    }
</script>

<body>
    <button id="get" onclick="return(false);">get</button>
    <button id="post" onclick="return(false);">post</button>
</body>

Update March 2012 2012年3月更新

Looks like the upcoming Microsoft WebAPI will serialize to ISO8601 thanks to Scott Hanselman and James Newton-King 由于Scott Hanselman和James Newton-King,看起来即将推出的Microsoft WebAPI将序列化为ISO8601

There's an issue with the way dates are handled. 处理日期的方式存在问题。 The JavaScriptSerializer uses the following format when dealing with dates: /Date(1302296382818)/ which unfortunately makes little sense to jQuery when parsing the GET JSON response so you don't get a real date on the client side but string. JavaScriptSerializer在处理日期时使用以下格式: /Date(1302296382818)/遗憾的是,在解析GET JSON响应时,jQuery对于jQuery没什么意义,所以你没有在客户端得到真正的日期而是字符串。 So you need a shameless hack in order to convert this string to a real date: 因此,为了将此字符串转换为实际日期,您需要一个无耻的黑客:

myData.Start = new Date(parseInt(data.Start.substr(6)));

And here's the full story of the hack: 这是黑客的完整故事:

Model: 模型:

public class Product
{
    public int Id { get; set; }
    public DateTime Start { get; set; }
}

Controller: 控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Data()
    {
        var product = new Product
        {
            Id = 1,
            Start = DateTime.Now,
        };
        return Json(product, JsonRequestBehavior.AllowGet);
    }

    [HttpPost]
    public ActionResult Data(Product product)
    {
        return Json(product);
    }
}

View: 视图:

<script type="text/javascript">
    var myData;

    function getData(event) {
        $.getJSON('/home/data', function (data) {
            myData = data;
            myData.Start = new Date(parseInt(data.Start.substr(6)));
        });
        return false;
    }

    function changeData(event)
    {
        var postData = JSON.stringify(myData);

        $.ajax({
            url: '/home/data',
            type: 'POST',
            data: postData,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            success: function (result) {
                console.log(result);
            }
        });

        return false;
    }

    $(function () {
        $('#get').click(getData);
        $('#post').click(changeData);
    });
</script>

<button id="get">get</button>
<button id="post">post</button>

Leaving the TimeSpan case as an exercise to the reader as it will require another shameless hack and I am tired of hacks :-) TimeSpan案例作为练习TimeSpan读者,因为它需要另一个无耻的黑客,我厌倦了黑客:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM