正确的方法来转换JSON日期到.NET日期时间反序列化过程 [英] Proper Way to Convert JSON Date to .NET DateTime During Deserialization
问题描述
我有一个调用一个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屋!