我有一个使用 JSON 数据调用 MVC 控制器的 javascript 函数:
var specsAsJson = JSON.stringify(specs);
$.post('/Home/Save', { jsonData: specsAsJson });
在服务器端,在控制器内,我似乎无法克服这个错误:
/Date(1347992529530)/ 不是 DateTime 的有效值。
当我调用 Deserialize() 时发生该异常(下面方法中的第三行):
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);
}
我一直在做一些谷歌搜索,上面的代码是我完成这项工作的最新尝试(使用此处的 TimeSpanJsonConverter )。其他方法显示仅向服务器发送日期,但我有一个将日期作为某些属性的对象列表。
是否有一种优雅的、普遍接受的方法来解决这个问题,还是我们仍然需要某种丑陋的解决方法?解决这个问题的正确方法是什么?
=================== 原始问题结束===================
编辑 - 通过使用 JsonConvert 序列化解决
请参阅下面的答案(不是这个问题中糟糕的解决方法)。
编辑 - 糟糕的解决方法
我创建了一个具有与域对象完全相同的字段的 DTO,除了我创建了日期字段字符串以便它们可以反序列化。现在我可以反序列化它,我将努力将日期转换为有效格式,以便我可以从我的 DTO 创建域对象。
public class EquipmentSpecDto
{
public string StartTime { get; set; }
public string EndTime { get; set; }
// more properties here
}
我只是使用 DTO 进行反序列化:
var specs = serializer.Deserialize<List<EquipmentSpecDto>>(jsonData);
编辑 2 - 将 JavaScript 日期转换为 .NET
为了完整起见,并希望我为别人节省一个小时,这就是我能够转换 javascript 日期的方式:
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);
}