2015-07-30 18 views
7

Mentre ho trovato molti approcci per deserializzare proprietà specifiche impedendo loro di serializzare, sto cercando il comportamento opposto.Serializzare la proprietà, ma non deserializzare la proprietà in Json.Net

ho trovato un sacco di domande che chiedono l'inverso:

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)

Come posso serializzare una proprietà specifica, ma evitare che la deserializzazione di nuovo alla POCO? C'è un attributo che posso usare per decorare la proprietà specifica?

Fondamentalmente sto cercando un equivalente ai metodi ShouldSerialize * per la deserializzazione.

So che posso scrivere un convertitore personalizzato, ma sembra eccessivo per questo.

Edit:

Ecco un po 'di più contesto. La ragione di questo è la mia classe si presenta come:

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; } 
} 

Ho bisogno la proprietà CountryProvinceState per la richiesta, ma non voglio che per deserializzare indietro e innescare la logica setter.

+0

Come si vuole fare un non cosa standard senza personalizzazione? –

+0

Voglio cambiare il comportamento senza dover scrivere e registrare una classe di convertitore personalizzata. Allo stesso modo, esistono diverse opzioni per gestire il contrario di questa situazione (utilizzando attributi o l'aggiunta di metodi ShouldSerialize *) senza dover scrivere una classe di convertitore personalizzata. –

+2

Apparentemente non sono l'unica persona che sta cercando di fare questo, come ho appena trovato questa domanda da oggi: http://stackoverflow.com/questions/31722033/json-net-webapi2-serialize-property-but-skip -during-deserialization –

risposta

12

metodo più semplice sarebbe quella di segnare la proprietà reale come [JsonIgnore] e creare una proprietà di 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; } 
    } 

La proprietà proxy può essere privato, se si desidera.

Aggiornamento

Se dovete fare questo per un sacco di immobili a un sacco di classi, potrebbe essere più facile per creare il proprio ContractResolver che verifica la presenza di un attributo personalizzato. Se trovato, l'attributo segnalerebbe che la proprietà è ottenere solo:

[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; 
    } 
} 

Poi utilizzarlo come:

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

E poi:

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

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

Bello.Fammi una prova e accetterò una volta che convaliderò che funziona. Grazie. –

+0

Se è necessario eseguire questa operazione per * lotti * di proprietà, è piuttosto semplice creare un ['ContractResolver'] (http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultContractResolver.htm) che verifica la presenza di attributo personalizzato Bisogno di essa? – dbc

+2

Ha funzionato come un fascino quando l'ho provato. Penso che questo sia l'unico ad essere onesto, ma se ce l'hai, sono sicuro che sarebbe utile per le persone in futuro. I posteri ti ringrazieranno per il tuo servizio al mondo, amico mio. –

Problemi correlati