2016-12-25 98 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); 
     } 
    }