正确的方法来转换JSON日期到.NET日期时间反序列化过程 [英] Proper Way to Convert JSON Date to .NET DateTime During Deserialization

查看:483
本文介绍了正确的方法来转换JSON日期到.NET日期时间反序列化过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个调用一个MVC控制器JSON数据的JavaScript函数:

  VAR specsAsJson = JSON.stringify(规格) ; 
$。员额('/主页/保存,{jsonData:specsAsJson});

在服务器端,在控制器内,我似乎无法让过去这个错误:




/日期(1347992529530)/不是日期时间的有效值。


$ b $

 公开:乙

这是例外,当我打电话反序列化()(如下方法三线)发生的ActionResult保存(字符串jsonData)
{
无功序列化=新的JavaScriptSerializer();
serializer.RegisterConverters(新[] {新TimeSpanJsonConverter()});
VAR规格= serializer.Deserialize<名单,LT; EquipmentSpecWithParameterlessConstructor>>(jsonData);

返回视图(指数,_allTrackerJobs);
}



我已经做了一些google搜索,和上面的代码是我最新的尝试为使这项工作(使用的TimeSpanJsonConverter这里)。其他的方法展示只发送日期到服务器上,但我有日期为某些属性的对象的列表。



有一种优雅的,普遍接受的方法解决这个,还是我们仍然需要某种丑陋的变通?什么是解决这一正确的方式?



===================原题结束= ==================






编辑 - 通过使用JsonConvert



请参阅我的答案以下序列化解决(不是蹩脚的工作围绕这个问题)。






修改 - 蹩脚的解决方法



我创建了一个DTO具有完全相同的字段域对象,但我做了日期字段字符串,这样他们就反序列化。现在,我可以反序列化,我将获得日期,有效的格式,所以我可以创建从我的DTO的域对象的工作。

 公共类EquipmentSpecDto 
{
公共字符串开始时间{获得;组; }
公共字符串结束时间{获得;组; }
//更多的属性在这里
}

和我只是简单地用DTO的反序列化:

  VAR规格= serializer.Deserialize<名单< EquipmentSpecDto>>(jsonData); 






修改2 - 转换的JavaScript日期至.NET



有关完整性,并在这我救了别人一小时的希望,这是我能够给JavaScript日期转换:

 的foreach(EquipmentSpecDto specDto在specDtos)
{
// JavaScript使用的Unix纪元1/1 / 1970年。请注意,它调用ToLocalTime()
//做一次转换后是很重要的,否则我们将不得不应对夏令时的胡言乱语。
的DateTime unixEpoch =新日期时间(1970年,1,1,0,0,0,DateTimeKind.Utc);
双击startMilliseconds = Convert.ToDouble(specDto.StartTime.Substring(6,13));
双击endMilliseconds = Convert.ToDouble(specDto.EndTime.Substring(6,13));
日期时间STARTTIME = unixEpoch.AddMilliseconds(startMilliseconds).ToLocalTime();
DateTime的结束时间= unixEpoch.AddMilliseconds(endMilliseconds).ToLocalTime();
EquipmentSpec规格=新EquipmentSpec(startTime时,结束时间,specDto.Equipment);

specs.Add(规范);
}


解决方案

我发现了一个简单的答案。在我的javascript,我被序列化使用的JavaScriptSerializer的数据。很多google搜索后,我发现这文章展示了如何使用JsonConvert导致更.NET友好的日期时间被用来序列



旧:

  VAR规格= @ Html.Raw(新System.Web.Script.Serialization.JavaScriptSerializer()。序列化(ViewBag.JobSpecEquipment))

日期如下:日期(1348017917565)



  VAR规格= @Html .RAW(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.JobSpecEquipment)); 



日期如下: 2012-09-18T21:27:31.1285861- 4时



所以这个问题真的我怎么被摆在首位序列。有一次,我用JsonConvert,在后端反序列化简单的工作。


I have a javascript function that calls an MVC controller with JSON data:

var specsAsJson = JSON.stringify(specs);
$.post('/Home/Save', { jsonData: specsAsJson });

On the server side, within the controller, I can't seem to get past this error:

/Date(1347992529530)/ is not a valid value for DateTime.

That exception happens when I call Deserialize() (third line in method below):

    public ActionResult Save(string jsonData)
    {
        var serializer = new JavaScriptSerializer();
        serializer.RegisterConverters(new[] { new TimeSpanJsonConverter() });
        var specs = serializer.Deserialize<List<EquipmentSpecWithParameterlessConstructor>>(jsonData);

        return View("Index", _allTrackerJobs);
    }

I've been doing some googling, and the above code is my latest attempt to make this work (using the TimeSpanJsonConverter from here). Other approaches show sending only a date to the server, but I have a list of objects that have dates as some properties.

Is there an elegant, generally-accepted approach to solving this, or do we still need some kind of ugly work-around? What's the right way to resolve this?

=================== End of original question ===================


Edit - SOLVED by serializing using JsonConvert

See my answer below (not the crappy work-around in this question).


Edit - Crappy work-around

I created a DTO with the exact same fields as the domain object, except that I made the date fields strings so they would deserialize. Now that I can deserialize it, I'll work on getting the dates into a valid format so I can create domain objects from my DTOs.

public class EquipmentSpecDto
{
    public string StartTime { get; set; }
    public string EndTime { get; set; }
    // more properties here
}

And I simply just used the DTO for the deserialization:

var specs = serializer.Deserialize<List<EquipmentSpecDto>>(jsonData);


Edit 2 - Converting JavaScript Dates to .NET

For completeness, and in the hopes that I save someone else an hour, this is how I was able to convert the javascript dates:

    foreach (EquipmentSpecDto specDto in specDtos)
    {
        // JavaScript uses the unix epoch of 1/1/1970. Note, it's important to call ToLocalTime()
        // after doing the time conversion, otherwise we'd have to deal with daylight savings hooey.
        DateTime unixEpoch       = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        Double startMilliseconds = Convert.ToDouble(specDto.StartTime.Substring(6, 13));
        Double endMilliseconds   = Convert.ToDouble(specDto.EndTime.Substring(6, 13));
        DateTime startTime       = unixEpoch.AddMilliseconds(startMilliseconds).ToLocalTime();
        DateTime endTime         = unixEpoch.AddMilliseconds(endMilliseconds).ToLocalTime();
        EquipmentSpec spec       = new EquipmentSpec(startTime, endTime, specDto.Equipment);

        specs.Add(spec);
    }

解决方案

I found a simple answer. In my javascript, I was serializing the data using the JavaScriptSerializer. After much googling, I found this article that shows how to serialize using JsonConvert that causes a more .NET-friendly DateTime to be used.

Old:

var specs = @Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(ViewBag.JobSpecEquipment))

Dates look like this: Date(1348017917565)

New:

var specs = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.JobSpecEquipment));

Dates look like this: 2012-09-18T21:27:31.1285861-04:00

So the problem was really how I was serializing in the first place. Once I used JsonConvert, deserialization on the back end simply worked.

这篇关于正确的方法来转换JSON日期到.NET日期时间反序列化过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆