В приложении MVC 3, как я могу сделать простой AJAX / JSON обход DateTimes и TimeSpans? - PullRequest
1 голос
/ 09 апреля 2011

Учитывая простой сценарий циклического отключения, как я могу вернуть данные JSON в браузер, а затем принять обновления из браузера через JSON, которые ModelBinding привязывает к типу с 3 свойствами: Int32, DateTime, TimeSpan?

Код сервера (контроллер)

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

Ошибки из непосредственного окна

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

Код клиента (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>

Обновление за март 2012 года

Похоже, что предстоящий Microsoft WebAPI будет сериализован в ISO8601 благодаря Скотту Хансельману и Джеймсу Ньютон-Кингу

1 Ответ

4 голосов
/ 09 апреля 2011

Существует проблема с обработкой дат. JavaScriptSerializer использует следующий формат при работе с датами: /Date(1302296382818)/, который, к сожалению, не имеет большого смысла для jQuery при синтаксическом анализе ответа GET JSON, поэтому вы не получаете реальную дату на стороне клиента, кроме строки.Так что вам нужен бесстыдный хак, чтобы преобразовать эту строку в реальную дату:

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

А вот полная история взлома:

Модель:

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

Контроллер:

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

Просмотр:

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

Оставление кейса TimeSpan в качестве упражнения для читателя, поскольку для него потребуется еще один бесстыдный взлом, и я устал от взломов-)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...