2016-12-25 42 views
1

我们在我们的项目中使用Json.Net来序列化和反序列化json对象。如何将属性添加到json对象上?

我们的实体有一些DateTime性质,我希望能够将它们转换成PersianCalender DateTime,并为他们在我的JSON对象的字符串:

例如,我们有这样的实体:

public class PersonCertificate 
{ 
     public DateTime CertificateDate{get;set;} 
} 

我想有一个JSON对象是这样的:

{ 
    "PersianCertificateDate":"1395/10/10" 
} 

所以我认为这将是巨大的,有一个属性命名“AsPersianDate”例如,这样我可以做这样的事情:

public class PersonCertificate 
{ 
     [JsonIgnore] 
     [AsPersianDate] 
     public DateTime CertificateDate{get;set;} 
} 

我知道我可以有一个自定义的合同解析器拦截JSON的创造过程,但我不知道我应该怎么告诉Json.Net反序列化PersianCertificateDate分成CertificateDate

+0

您可以添加第二个属性,它会留下当你做json到object的时候是空的,因为json没有那个属性。但是,你可以根据Date来计算它,然后你的object-to-json会得到这些额外的数据。 – SimpleVar

+0

这就是我现在正在做的问题是我必须为所有实体添加这些额外的属性,但是当我想序列化和反序列化我的对象时,我只需要它们。 – Beatles1692

+0

因此,创建一个只添加这些属性的派生类,并且仅用于序列化和反序列化,并且您的“真实”类保持干净。派生类甚至可以是一个类中的私有类,所以它们甚至不会为整个项目中的intellisense添加垃圾。 – SimpleVar

回答

1

确定它是更容易比我thought.Actually ContractResolver负责获取和所以在这里设置所有属性值是我做了什么:

public class EntityContractResolver:DefaultContractResolver 
    { 
     private class PersianDateValueProvider:IValueProvider 
     { 
      private readonly PropertyInfo _propertyInfo; 

      public PersianDateValueProvider(PropertyInfo propertyInfo) 
      { 
       _propertyInfo = propertyInfo; 
      } 


      public void SetValue(object target, object value) 
      { 
       try 
       { 
        var date = value as string; 
        if(value==null && _propertyInfo.PropertyType==typeof(DateTime)) 
         throw new InvalidDataException(); 
        _propertyInfo.SetValue(target,date.ToGregorianDate()); 
       } 
       catch (InvalidDataException) 
       { 
        throw new ValidationException(new[] 
        { 
         new ValidationError 
         { 
          ErrorMessage = "Date is not valid", 
          FieldName = _propertyInfo.Name, 
          TypeName = _propertyInfo.DeclaringType.FullName 
         } 
        }); 
       } 
      } 

      public object GetValue(object target) 
      { 
       if(_propertyInfo.PropertyType.IsNullable() && _propertyInfo.GetValue(target)==null) return null; 
       try 
       { 
        return ((DateTime) _propertyInfo.GetValue(target)).ToPersian(); 
       } 
       catch 
       { 
        return string.Empty; 
       } 

      } 
     } 


     protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
     { 
      var list= base.CreateProperties(type, memberSerialization).ToList(); 
      list.AddRange(type.GetProperties() 
       .Where(pInfo => IsAttributeDefined(pInfo,typeof(AsPersianDateAttribute))&& (pInfo.PropertyType == typeof (DateTime) || pInfo.PropertyType == typeof (DateTime?))) 
       .Select(CreatePersianDateTimeProperty)); 
      return list; 
     } 

     private JsonProperty CreatePersianDateTimeProperty(PropertyInfo propertyInfo) 
     { 
      return new JsonProperty 
      { 
       PropertyName = "Persian"+propertyInfo.Name , 
       PropertyType = typeof (string), 
       ValueProvider = new PersianDateValueProvider(propertyInfo), 
       Readable = true, 
       Writable = true 
      }; 
     } 

     private bool IsAttributeDefined(PropertyInfo propertyInfo,Type attribute) 
     { 
      var metaDataAttribute = propertyInfo.DeclaringType.GetCustomAttribute<MetadataTypeAttribute>(true); 
      var metaDataProperty = metaDataAttribute?.MetadataClassType?.GetProperty(propertyInfo.Name); 
      var metaDataHasAttribute = metaDataProperty != null && Attribute.IsDefined(metaDataProperty, attribute); 

      return metaDataHasAttribute || Attribute.IsDefined(propertyInfo, attribute); 
     } 
    }