WCF DataContractJsonSerializer如何将DateTime对象设置为UTC?

3

是否有一种通用的方法可以指示DataContractJsonSerializer使用UTC日期?否则,我必须在所有日期实例中添加.ToUniversalTime()。这种情况可能吗?原因是日期值默认为DateTimeKind.Local并向JSON结果添加偏移量。将日期设为通用类型就可以解决问题,但是否可以在全局级别上完成?谢谢。

1个回答

3

在全局级别无法直接实现这一点 - 原始类型(如 DateTime)无法被“代理”。一个可能的解决方法是在序列化对象时使用某种反射和代理来更改 DateTime 字段(或属性),如下面的示例所示。

public class StackOverflow_6100587_751090
{
    public class MyType
    {
        public MyTypeWithDates d1;
        public MyTypeWithDates d2;
    }
    public class MyTypeWithDates
    {
        public DateTime Start;
        public DateTime End;
    }
    public class MySurrogate : IDataContractSurrogate
    {
        public object GetCustomDataToExport(Type clrType, Type dataContractType)
        {
            throw new NotImplementedException();
        }

        public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
        {
            throw new NotImplementedException();
        }

        public Type GetDataContractType(Type type)
        {
            return type;
        }

        public object GetDeserializedObject(object obj, Type targetType)
        {
            return obj;
        }

        public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
        {
        }

        public object GetObjectToSerialize(object obj, Type targetType)
        {
            return ReplaceLocalDateWithUTC(obj);
        }

        public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
        {
            throw new NotImplementedException();
        }

        public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
        {
            throw new NotImplementedException();
        }

        private object ReplaceLocalDateWithUTC(object obj)
        {
            if (obj == null) return null;
            Type objType = obj.GetType();
            foreach (var field in objType.GetFields())
            {
                if (field.FieldType == typeof(DateTime))
                {
                    DateTime fieldValue = (DateTime)field.GetValue(obj);
                    if (fieldValue.Kind != DateTimeKind.Utc)
                    {
                        field.SetValue(obj, fieldValue.ToUniversalTime());
                    }
                }
            }

            return obj;
        }
    }
    public static void Test()
    {
        MemoryStream ms = new MemoryStream();
        DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(MyType), null, int.MaxValue, true, new MySurrogate(), false);
        MyType t = new MyType
        {
            d1 = new MyTypeWithDates { Start = DateTime.Now, End = DateTime.Now.AddMinutes(1) },
            d2 = new MyTypeWithDates { Start = DateTime.Now.AddHours(1), End = DateTime.Now.AddHours(2) },
        };
        dcjs.WriteObject(ms, t);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接