2016-06-05 3 views
1

으로 직렬화 복원 할 때 사용자 정의 클래스의 DefaultValue를 전달하는 방법은이 같은 JSON 구조를 직렬화하는 :는 Json.net

{ 
    "Name": "Foo", 
    "bar": { 
     "Name": "Bar", 
     "DefaultableProperty": "default" 
    } 
} 

를 ... "bar"을 정의하는 옵션입니다. 그리고 그것이 정의되어 있지 않은 경우, 어떤 기본값을 가지고 타입 Bar의 객체를로드하고 싶습니다. 내가의 개체를 역 직렬화 할 수 있어요 위의 코드를 사용하여

[TestMethod] 
public void CanDeserializeObjectWithDefaultValues() 
{ 
    string s = @"{ 'Name': 'aname', 
        }"; 
    Foo foo = JsonConvert.DeserializeObject<Foo>(s); 
    Assert.AreEqual("aname", foo.Name); 
    Assert.AreEqual("default", foo.bar.DefaultableProperty); 
    Assert.IsNotNull(foo.bar.Name); 
} 

:

여기 FooBar 내 클래스 정의는

public class Foo 
{ 
    [JsonConstructor] 
    public Foo() 
    { 
     string bardefaults = @"{ ""Name"": ""defaultname""}"; 
     b = new Bar(bardefaults); 
    } 
    public string Name { get; set; } 
    public Bar bar { get; set; } 
} 

public class Bar 
{ 
    public Bar() { } 
    public Bar(string json) 
    { 
     Bar copy = JsonConvert.DeserializeObject<Bar>(json); 
     Name = copy.Name; 
     DefaultableProperty = copy.DefaultableProperty; 
    } 
    public string Name { get; set; } 

    [DefaultValue("default")] 
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] 
    public string DefaultableProperty { get; set; } 
} 

그리고 여기에 몇 가지 JSON을 역 직렬화 내 시험 방법되고있다 그것의 기본값과 함께 막대를 입력하십시오. 그러나 Bar.DefaultableProperty처럼 Foo.barDefaultValue을 사용하고 싶습니다. 나는 다음과 같은 구문을 사용하여이를 달성 할 수 없었던 :

  • [DefaultValue(typeof(Bar), @"{ ""Name"": ""bar"" }")]
  • [DefaultValue(new Bar(@"{ ""Name"": ""bar"" }"))]
  • 그래서 내 질문은

      은 기본 사용자 지정 개체의 창조를위한 일부 지원을 Json.NET합니까? 그렇지 않다면이 상황에 접근하는 가장 좋은 방법은 무엇입니까?

      public class JsonDefaultValueAttribute : DefaultValueAttribute 
      { 
          public JsonDefaultValue(string json, Type type) : base (ConvertFromJson(json, type)) 
          {    
          } 
      
          private static object ConvertFromJson(string json, Type type) 
          { 
           var value = JsonConvert.DeserializeObject(json, type, new JsonSerializerSettings 
           { 
            MissingMemberHandling = MissingMemberHandling.Error, 
            NullValueHandling = NullValueHandling.Include, 
            DefaultValueHandling = DefaultValueHandling.Populate 
           }); 
      
           return value; 
          } 
          .... 
      } 
      

      이제 새로운 속성을 사용할 수 있습니다 : 나는 다음과 같은 유형을 대상으로 JSON 문자열 값을 변환 지원하는 새의 ctor DefaultValueAttribute에서 파생되는 새로운 JsonDefaultValueAttribute 속성을 작성했고, 추가 무엇

    +1

    나는 생각한다. [DefaultValue (typeof (Bar), @ "{" "Name}": ""bar ""} ")]'[적절한'TypeConverter'와'JsonConverter' ] (https://stackoverflow.com/questions/31325866) - 그러나 문제가 있습니다 : ['DefaultValueAttribute.Value'] (https://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute .value.aspx)는 단지 하나의 객체이고'Bar' 클래스는 * mutable *이므로'Foo'에 설정하면 전역 인스턴스에 대한 참조가 모든 곳에 저장되어 수정됩니다. – dbc

    +0

    그런데 직렬화 및 복사보다는 ['JsonConvert.PopulateObject()'] (http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_JsonConvert_PopulateObject.htm)를 사용하면 코드를 상당히 단순화 할 수 있습니다. . – dbc

    답변

    0

    기본값을 사용하는 대신