Подтвердить что ты не робот

Передача формата JSON DateTime в ASP.NET MVC

Мы знаем, что MVC возвращает DateTime для JsonResult в этом формате: /Date(1240718400000)/, и мы знаем, как его анализировать в JS.

Однако, похоже, что MVC не принимает параметр DateTime, отправляемый таким образом. Например, у меня есть следующее действие.

[HttpGet]
public ViewResult Detail(BookDetail details) { //... }

Класс BookDetail содержит поле DateTime с именем CreateDate, и я передал объект JSON из JS в этом формате:

{"CreateDate": "/Date(1319144453250)/"}

CreateDate распознается как null.

Если я передал JSON таким образом, он работает как ожидалось:

{"CreateDate": "2011-10-10"}

Проблема заключается в том, что я не могу легко изменить код на стороне клиента, должен придерживаться /Date (1319144453250)/этого формата. Я должен внести изменения на стороне сервера.

Как решить эту проблему? Это что-то связано с ModelBinder?

Большое спасибо заранее!

4b9b3361

Ответ 1

Проблема, как вы подозревали, является проблемой, связанной с моделью.

Чтобы обойти это, создайте собственный тип и позвоните ему JsonDateTime. Поскольку DateTime является структурой, вы не можете наследовать ее, поэтому создайте следующий класс:

public class JsonDateTime
{
    public JsonDateTime(DateTime dateTime)
    {
        _dateTime = dateTime;
    }

    private DateTime _dateTime;

    public DateTime Value
    {
        get { return _dateTime; }
        set { _dateTime = value; }
    }
}

Измените CreateDate для этого типа. Затем нам понадобится настраиваемое связующее устройство, например:

public class JsonDateTimeModelBinder : IModelBinder  
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).ToString(); 
        return new DateTime(Int64.Parse(
            value.Substring(6).Replace(")/",String.Empty))); // "borrowed" from skolima answer
    }
}

Затем в Global.asax.cs в Application_Start зарегистрируйте свой собственный ModelBinder:

ModelBinders.Binders.Add(typeof(JsonDateTime), new JsonDateTimeModelBinder());

Ответ 2

В вашей модели используйте это, чтобы проанализировать дату:

// property
String CreateDate;
DateTime CreateDateAsDate;

// drop prefix, drop suffix, parse as long and read as ticks
CreateDateAsDate date = new DateTime(Int64.Parse(
    CreateDate.Substring(6).Replace(")/",String.Empty)));

Ответ 3

Я думаю, что использование пользовательской модели Binder сделает трюк. Следующий класс связующего класса будет работать в обоих случаях. Он будет анализировать всю строку распознаваемой даты dot, а также строку даты форматирования JSON. Не нужно изменять какой-либо существующий код.

public class DateTimeModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = base.BindModel(controllerContext, bindingContext);
        if (model == null && (bindingContext.ModelType == typeof(DateTime) || bindingContext.ModelType == typeof(DateTime?)))
        {
            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (value == null || String.IsNullOrEmpty(value.AttemptedValue))
                model = (bindingContext.ModelType == typeof(DateTime?)) ? null : (object)DateTime.MinValue;
            else if (Regex.IsMatch(value.AttemptedValue, @"\/Date\(\d+\)\/"))
                model = new DateTime(1970, 1, 1).AddMilliseconds(Int64.Parse(value.AttemptedValue.Substring(6).Replace(")/", String.Empty))).ToLocalTime();
            //else //Any other format
        }
        return model;
    }
}

Настроить привязку модели в Application_Start из Global.asax

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        //Your Existing Code....

        ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder());
        ModelBinders.Binders.Add(typeof(DateTime?), new DateTimeModelBinder());
    }
}

Голосовать Если это помогает