Asp.net mvc 2 JavaScriptSerializer未正确反序列化DateTime/TimeSpan

Asp.net mvc 2 JavaScriptSerializer未正确反序列化DateTime/TimeSpan,asp.net-mvc-2,datetime,timespan,javascriptserializer,Asp.net Mvc 2,Datetime,Timespan,Javascriptserializer,存在DateTime/TimeSpan似乎无法使用JavaScriptSerializer正确反序列化的问题。 当我在反序列化后返回对象时,TimeSpan为空,如果我使用DateTime,则时间都不正常。 我确实找到了这篇文章,但对我帮助不大。 有人有什么想法吗?我应该试试json.net库吗 public class JsonFilter : ActionFilterAttribute { public string Param { get; set; } public T

存在DateTime/TimeSpan似乎无法使用JavaScriptSerializer正确反序列化的问题。 当我在反序列化后返回对象时,TimeSpan为空,如果我使用DateTime,则时间都不正常。 我确实找到了这篇文章,但对我帮助不大。

有人有什么想法吗?我应该试试json.net库吗

public class JsonFilter : ActionFilterAttribute
{
    public string Param { get; set; }
    public Type JsonDataType { get; set; }
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
        {
            string inputContent;
            using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
            {
                inputContent = sr.ReadToEnd();
            }

            JavaScriptSerializer serializer = new JavaScriptSerializer();
            var result = serializer.Deserialize(inputContent, JsonDataType);
            filterContext.ActionParameters[Param] = result;
        }
    }
}

public class RosterItem
{
    public RosterItem()
    {
        comments = new List<Form.Comment>();
    }
    public Boolean dirty { get; set; }
    public int id { get; set; }
    public int staffId { get; set; }
    public String description { get; set; }
    public int activityId { get; set; }
    public DateTime date { get; set; }
    public TimeSpan startTime { get; set; }
    public TimeSpan endTime { get; set; }
    public List<Form.Comment> comments { get; set; }
}

    [JsonFilter(Param = "rosterItem", JsonDataType = typeof(RosterItem))]
    public int SaveRosterEntry(RosterItem rosterItem)
    {
        RosterEntry rosterEntry = rosterEntryRepository.GetRosterEntry(rosterItem.id);
        if (rosterEntry == null)
        {
            rosterEntry = new RosterEntry();
            rosterEntryRepository.Add(rosterEntry);
        }
        rosterEntry.ActivityID = rosterItem.activityId;
        rosterEntry.StartTime = rosterItem.startTime;
        rosterEntry.EndTime = rosterItem.endTime;
        rosterEntry.RosterDate = rosterItem.date;
        rosterEntry.RosterEmployeeID = rosterItem.staffId;            
        rosterEntryRepository.Save();
        return rosterEntry.RosterEntryID;
    }
public类JsonFilter:ActionFilterAttribute
{
公共字符串参数{get;set;}
公共类型JsonDataType{get;set;}
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
if(filterContext.HttpContext.Request.ContentType.Contains(“应用程序/json”))
{
字符串输入内容;
使用(var sr=newstreamreader(filterContext.HttpContext.Request.InputStream))
{
inputContent=sr.ReadToEnd();
}
JavaScriptSerializer serializer=新的JavaScriptSerializer();
var result=serializer.Deserialize(inputContent,JsonDataType);
filterContext.ActionParameters[Param]=结果;
}
}
}
公共类名册
{
公共名册()
{
注释=新列表();
}
公共布尔脏{get;set;}
公共int id{get;set;}
public int staffId{get;set;}
公共字符串说明{get;set;}
public int activityId{get;set;}
公共日期时间日期{get;set;}
公共时间跨度开始时间{get;set;}
公共时间跨度结束时间{get;set;}
公共列表注释{get;set;}
}
[JsonFilter(Param=“rosterItem”,JsonDataType=typeof(rosterItem))]
公共int保存RosterEntry(RosterItem RosterItem)
{
RosterEntry-RosterEntry=rosterEntryRepository.GetRosterEntry(rosterItem.id);
if(rosterEntry==null)
{
rosterEntry=新的rosterEntry();
rosterEntryRepository.Add(rosterEntry);
}
rosterEntry.ActivityID=rosterItem.ActivityID;
rosternetry.StartTime=rosterItem.StartTime;
rosterEntry.EndTime=rosterItem.EndTime;
rosterEntry.RosterDate=rosterItem.date;
rosterEntry.RosterEmployeeID=rosterItem.staffId;
rosterEntryRepository.Save();
返回rosternetry.rosternetryid;
}

如果您遇到同样的问题,这将解决您的问题


所有DateTime对象都需要显式指定为UTC

我在GitHub上的以下帖子中找到了答案:

基本上,答案是创建一个新的
TimeSpanJsonConverter
,该转换器继承自
JavaScriptConverter
,然后将其传递给序列化器类的实例:

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer()
serializer.RegisterConverters(new[] { new TimeSpanJsonConverter() });
供参考的完整类为(作者):

公共类TimeSpanJsonConverter:JavaScriptConverter { 公共覆盖IEnumerable SupportedTypes { 得到 { 返回新的[]{typeof(TimeSpan)}; } } 公共重写对象反序列化(IDictionary dictionary、类型、JavaScriptSerializer序列化程序) { 返回新的时间跨度( 这个.GetValue(字典中的“天”), 这个.GetValue(字典,“小时”), 这个.GetValue(字典,“分钟”), this.GetValue(字典中的“秒”), this.GetValue(字典中的“毫秒”); } 公共重写IDictionary序列化(对象obj、JavaScriptSerializer序列化程序) { var timeSpan=(timeSpan)obj; var result=新字典 { {“天”,timeSpan.days}, {“小时”,timeSpan.hours}, {“分钟”,timeSpan.minutes}, {“秒”,timeSpan.seconds}, {“毫秒”,timeSpan.millises} }; 返回结果; } 私有int GetValue(IDictionary字典,字符串键) { const int DefaultValue=0; 目标价值; if(!dictionary.TryGetValue(键,输出值)) { 返回默认值; } if(值为int) { 返回(int)值; } var valueString=作为字符串的值; if(valueString==null) { 返回默认值; } 返回值; return!int.TryParse(valueString,out returnValue)?DefaultValue:returnValue; } }
该解决方案非常适合解决TimeSpan序列化问题,但我认为这个问题与DateTime有关。
public class TimeSpanJsonConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(TimeSpan) };
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        return new TimeSpan(
            this.GetValue(dictionary, "days"),
            this.GetValue(dictionary, "hours"),
            this.GetValue(dictionary, "minutes"),
            this.GetValue(dictionary, "seconds"),
            this.GetValue(dictionary, "milliseconds"));
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var timeSpan = (TimeSpan)obj;

        var result = new Dictionary<string, object>
            {
                { "days", timeSpan.Days },
                { "hours", timeSpan.Hours },
                { "minutes", timeSpan.Minutes },
                { "seconds", timeSpan.Seconds },
                { "milliseconds", timeSpan.Milliseconds }
            };

        return result;
    }

    private int GetValue(IDictionary<string, object> dictionary, string key)
    {
        const int DefaultValue = 0;

        object value;
        if (!dictionary.TryGetValue(key, out value))
        {
            return DefaultValue;
        }

        if (value is int)
        {
            return (int)value;
        }

        var valueString = value as string;
        if (valueString == null)
        {
            return DefaultValue;
        }

        int returnValue;
        return !int.TryParse(valueString, out returnValue) ? DefaultValue : returnValue;
    }
}