2015-07-30 16 views
7

Podczas gdy znalazłem wiele podejść do deserializacji konkretnych właściwości, zapobiegając ich serializacji, szukam przeciwnego zachowania.Serialize Property, ale nie Deserialize Property w Json.Net

Znalazłem mnóstwo pytań z prośbą odwrotność:

Making a property deserialize but not serialize with json.net

Can I instruct Json.NET to deserialize, but not serialize, specific properties?

JSON.Net - Use JsonIgnoreAttribute only on serialization (But not when deserialzing)

Jak mogę serializacji konkretnej nieruchomości, ale uniemożliwić deserializacji z powrotem do POCO? Czy istnieje atrybut, który można wykorzystać do dekoracji konkretnej nieruchomości?

Zasadniczo szukam odpowiednika metody ShouldSerialize * dla deserializacji.

Wiem, że mogę napisać niestandardowy konwerter, ale to wydaje się przesadą.

Edytuj:

Oto trochę więcej kontekstu. Powodem tego jest mój klasy wygląda następująco:

public class Address : IAddress 
{ 
    /// <summary> 
    /// Gets or sets the two character country code 
    /// </summary> 
    [JsonProperty("countryCode")] 
    [Required] 
    public string CountryCode { get; set; } 

    /// <summary> 
    /// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c> 
    /// </summary> 
    [JsonProperty("countryProvinceState")] 
    public string CountryProvinceState 
    { 
     get 
     { 
      return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState); 
     } 
     set 
     { 
      if (!string.IsNullOrWhiteSpace(value) && value.Contains("|")) 
      { 
       string[] valueParts = value.Split('|'); 
       if (valueParts.Length == 2) 
       { 
        this.CountryCode = valueParts[0]; 
        this.ProvinceState = valueParts[1]; 
       } 
      } 
     } 
    } 

    [JsonProperty("provinceState")] 
    [Required] 
    public string ProvinceState { get; set; } 
} 

muszę nieruchomości na wniosek CountryProvinceState, ale nie chcę go z powrotem do deserializowania i wywołać logikę seter.

+0

Jak chcesz zrobić non -standardowe rzeczy bez personalizacji? –

+0

Chcę zmienić zachowanie bez konieczności pisania i rejestrowania niestandardowej klasy konwertera. Podobnie istnieje wiele opcji obsługi odwrotnej sytuacji (użycie atrybutów lub dodanie metod ShouldSerialize *) bez konieczności pisania niestandardowej klasy konwertera. –

+2

Wygląda na to, że nie jestem jedyną osobą, która próbuje to zrobić, ponieważ właśnie znalazłem to pytanie od dzisiaj: http://stackoverflow.com/questions/31722033/json-net-webapi2-serialize-property-but-skip -during-deserialization –

Odpowiedz

12

Najprostszą metodą byłoby oznaczyć nieruchomość jako [JsonIgnore] i utworzyć właściwość proxy Get-only:

/// <summary> 
    /// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c> 
    /// </summary> 
    [JsonIgnore] 
    public string CountryProvinceState 
    { 
     get 
     { 
      return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState); 
     } 
     set 
     { 
      if (!string.IsNullOrWhiteSpace(value) && value.Contains("|")) 
      { 
       string[] valueParts = value.Split('|'); 
       if (valueParts.Length == 2) 
       { 
        this.CountryCode = valueParts[0]; 
        this.ProvinceState = valueParts[1]; 
       } 
      } 
     } 
    } 

    [JsonProperty("countryProvinceState")] 
    string ReadCountryProvinceState 
    { 
     get { return CountryProvinceState; } 
    } 

Obiekt proxy mogą być prywatne, jeśli chcesz.

Aktualizacja

Jeśli musisz to zrobić na wiele właściwości w wielu klasach, może to być łatwiejsze do tworzenia własnych ContractResolver że sprawdza atrybutu niestandardowego. W przypadku stwierdzenia, atrybut będzie sygnalizować, że hotel znajduje się tylko:

[System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple = false)] 
public class GetOnlyJsonPropertyAttribute : Attribute 
{ 
} 

public class GetOnlyContractResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) 
    { 
     var property = base.CreateProperty(member, memberSerialization); 
     if (property != null && property.Writable) 
     { 
      var attributes = property.AttributeProvider.GetAttributes(typeof(GetOnlyJsonPropertyAttribute), true); 
      if (attributes != null && attributes.Count > 0) 
       property.Writable = false; 
     } 
     return property; 
    } 
} 

następnie używać go jak:

[JsonProperty("countryProvinceState")] 
[GetOnlyJsonProperty] 
public string CountryProvinceState { get; set; } 

, a następnie:

 var settings = new JsonSerializerSettings { ContractResolver = new GetOnlyContractResolver() }; 

     var address = JsonConvert.DeserializeObject<Address>(jsonString, settings); 
+0

Piękny.Przetestuj to na Lemme, a zaakceptuję, gdy potwierdzę, że działa. Dziękuję Ci. –

+0

Jeśli chcesz to zrobić dla * części * właściwości, całkiem łatwo jest stworzyć ['ContractResolver'] (http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultContractResolver.htm), który sprawdza niestandardowy atrybut. Potrzebuję tego? – dbc

+2

Pracowałem jak czar, kiedy testowałem. Myślę, że to jest jedyny szczery, ale jeśli go masz, jestem pewien, że przyniesie to korzyści ludziom w przyszłości. Potomność będzie ci wdzięczna za twoją służbę dla świata, mój przyjacielu. –