Даты нокаута reset на пост до контроллера mvc

У меня есть приложение для нокаута /mvc 3. Я передаю дату назад контроллеру.

контроллер

public ActionResult PackageUpdate(Package updatePackage){
\\do some stuff but dates are set to zero?
}

просмотреть модель и сохранить

var Package = function (data) {
    self = this;
    self = ko.mapping.fromJS(data);
    self.save = function(){
        $.ajax({
            url: '/MediaSchedule/PackageUpdate', 
            data:ko.toJSON({ updatePackage: self })
        }).success(function (results) {
            console.log(results);
        }).error(function (er) { 
            console.error('Ah damn you broke it.')
            console.log(er);
        });
    }
    return self;
}

Передано Json.

{"updatePackage":{"Id":"82e3bc7e-27b8-49c2-b1fa-1ee2ebffbe66","Name":"28a38","SecondaryName":"è€å­æˆ‘è¦é’±","IsLocked":true},"DateCreated":"/Date(1357650000000+1100)/","DateStart":"/Date(1365080400000+1100)/","DateEnd":"/Date(1365516000000+1000)/"}

Идентификатор, имя и другие свойства проходят, но дата составляет reset до {1/1/0001 12:00:00 AM}. Мое предположение состоит в том, что он не десериализуется, устанавливает минимальную дату. Вопрос: Как правильно десериализовать дату.

Ответ 1

Я думаю, что проблема заключается в том, как вы получаете эти даты для начала. Вы показываете пример с использованием формата даты MS, такого как /Date(1357650000000+1100)/, который не стандартизирован и медленно устарел в пользу ISO8601, который выглядит как 2013-01-08T13:00:00.000+11:00.

Действительно, когда вы JSON.stringify объект javascript Date, он использует формат ISO8601. Это также происходит с ko.mapping.toJSON.

Существует несколько решений этой проблемы, как на стороне клиента, так и на стороне сервера. Этот пост подробно описывает проблему и содержит отличные ответы, которые могут вам помочь.

IMHO, лучшее решение - заставить ваш контроллер MVC испускать и потреблять ISO8601, а не старый формат даты Microsoft. Самый простой способ сделать это - использовать библиотеку Json.Net который теперь имеет ISO8601 по умолчанию, поэтому вам даже не нужно его настраивать. На стороне клиента вы также можете посмотреть Moment.js - что позволяет легко анализировать и форматировать даты ISO.

Ответ 2

Я думаю, что это просто тип данных, который вы нажимаете на объект updatePackage. Ниже приведен мой код и хорошо работает, я использую значение Date из jQuery Datepicker и использую формат как "dd MM, yy" (01 января 2013 г.)

 var iEndInsuredDate = $('#dpkEndInsuredDate').val();
            var iEndPolicyDate = $('#dpkEndPolicyDate').val();

            $.ajax({
                url: '@Url.Action("DeleteClientMember", "ClientMember")',
                type: "POST",
                dataType: "json",
                data: { clientMemberID: id, endInsuredDate: iEndInsuredDate, endPolicyDate: iEndPolicyDate },
                success: function (result) {
                    ShowWaiting("Reloading...");
                    Search(1);
                }
            });

и мой ActionResult

public ActionResult DeleteClientMember(int clientMemberID, DateTime? endInsuredDate, DateTime? endPolicyDate)
    {
        ClientMember model = clientMemberService.GetById(clientMemberID);

        //model.EndPolicyDate = endPolicyDate;
        model.EndInsuredDate = endInsuredDate;
        foreach (ClientMemberProduct item in model.ProductList)
        {
            item.EndDate = endInsuredDate;
        }
        model.IsActive = false;
        model.ActionStatus = ClientMemberActionStatus.PendingDelete.ToString();
        clientMemberService.CalculateInsFee(model);
        clientMemberService.Update(model);
        return null;
    }

Надеюсь, что эта помощь Рассматривать

Ответ 3

Благодаря Matt Johnson мне удалось изменить способ отправки дат в браузер. Это было релятивистски легкое исправление, взятое из скоропортящегося Дэйва, в ответ на аналогичную проблему с Формат даты ASP.NET MVC JsonResult

Класс My JsonNetResult теперь выглядит как

public class JsonNetResult : ActionResult
{
    private const string _dateFormat = "yyyy-MM-dd hh:mm:ss";

    public Encoding ContentEncoding { get; set; }
    public string ContentType { get; set; }
    public object Data { get; set; }

    public JsonSerializerSettings SerializerSettings { get; set; }
    public Formatting Formatting { get; set; }

    public JsonNetResult()
    {
        SerializerSettings = new JsonSerializerSettings();
        Formatting = Formatting.Indented;
        SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        HttpResponseBase response = context.HttpContext.Response;

        response.ContentType = !string.IsNullOrEmpty(ContentType)
          ? ContentType
          : "application/json";

        if (ContentEncoding != null)
            response.ContentEncoding = ContentEncoding;

        if (Data != null)
        {
            var isoConvert = new IsoDateTimeConverter();
            isoConvert.DateTimeFormat = _dateFormat;

            JsonTextWriter writer = new JsonTextWriter(response.Output) { Formatting = Formatting };

            JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
            serializer.Converters.Add(isoConvert);

            serializer.Serialize(writer, Data);

            writer.Flush();
        }
    }
}

Я добавил преобразователь iso date в serizer

в контроллере вы вызываете его:

public JsonNetResult YourAction(){
    //your logic here
    return JsonNetResult(/*your object here*/);
}

Когда я написал это, я не знал о веб-API. Это стоит посмотреть, поскольку он будет делать большой тяжелый подъем, когда дело доходит до сериализации ваших объектов. Оформить заказ Начало работы с ASP.NET Web API 2