2016-12-16 80 views
0

我想創建一個自定義的JsonConverter,將C#屬性名稱更改爲駝峯大小寫和javascript/json屬性名稱以pascal大小寫。我覺得我走在正確的軌道上,但是我很難理解我需要做什麼(而且我處於緊張狀態)。ViewModel自定義JsonConverter

我知道我可以在JsonProperty屬性添加到我的C#的屬性,但我寧願一個屬性應用到類,而不是每個屬性。

public class ViewModelJsonConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var model = JObject.Load(reader); 
     var properties = model.Properties(); 
     foreach (var prop in properties) 
     { 
      RenameToPascalCase(prop.Name, prop.Value); 
     } 
     return model; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var model = (JObject)JToken.FromObject(value); 
     var properties = model.Properties(); 
     foreach (var prop in properties) 
     { 
      RenameToCamelCase(prop.Name, prop.Value); 
     } 
    } 


    private void RenameToCamelCase(string name, JToken value) 
    { 
     var parent = value.Parent; 
     if (parent == null) 
      throw new InvalidOperationException("The parent is missing."); 

     var newProperty = new JProperty(ToCamelCase(name), value); 
     parent.Replace(newProperty); 
    } 

    private void RenameToPascalCase(string name, JToken value) 
    { 
     var parent = value.Parent; 
     if (parent == null) 
      throw new InvalidOperationException("The parent is missing."); 

     var newProperty = new JProperty(ToPascalCase(name), value); 
     parent.Replace(newProperty); 
    } 

    //Example: propertyName 
    private string ToCamelCase(string value) 
    { 
     if (String.IsNullOrEmpty(value) || Char.IsLower(value, 0)) 
      return value; 

     return Char.ToLowerInvariant(value[0]) + value.Substring(1); 
    } 

    //Example: PropertyName 
    private string ToPascalCase(string value) 
    { 
     if (String.IsNullOrEmpty(value) || Char.IsUpper(value, 0)) 
      return value; 

     return Char.ToUpperInvariant(value[0]) + value.Substring(1); 
    } 
} 

樣品使用

[JsonConverter(typeof(ViewModelJsonConverter))] 
public class TestClass { 
    public string PropertyName { get; set; } 
} 

回答

1

如果您使用的是Json.Net 9.0.1或更高版本,則可以使用[JsonObject]屬性的NamingStrategyType參數進行操作。因此,換句話說,只要勾選你想成爲駱駝套管這樣的類:

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] 
public class TestClass 
{ 
    ... 
} 

你不需要ContractResolver或自定義JsonConverter

這是一個往返演示:

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     TestClass tc = new TestClass 
     { 
      PropertyName = "foo", 
      AnotherPropertyName = "bar" 
     }; 

     Console.WriteLine("--- Serialize ---"); 
     string json = JsonConvert.SerializeObject(tc, Formatting.Indented); 
     Console.WriteLine(json); 
     Console.WriteLine(); 

     Console.WriteLine("--- Deserialize ---"); 
     TestClass test = JsonConvert.DeserializeObject<TestClass>(json); 
     Console.WriteLine("PropertyName: " + test.PropertyName); 
     Console.WriteLine("AnotherPropertyName: " + test.AnotherPropertyName); 
    } 
} 

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] 
public class TestClass 
{ 
    public string PropertyName { get; set; } 
    public string AnotherPropertyName { get; set; } 
} 

輸出:

--- Serialize --- 
{ 
    "propertyName": "foo", 
    "anotherPropertyName": "bar" 
} 

--- Deserialize --- 
PropertyName: foo 
AnotherPropertyName: bar 
0

你有沒有試過任何對newtonsoft JSON這些合同解析器。 對於如:

var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; 
var json = JsonConvert.SerializeObject(obj, Formatting.Indented, jsonSerializerSettings); 

如果你想實現自己的話,請無視。

+0

我不知道這一點,但我需要將它應用到一個特定的類。這看起來更像是一個全球變化。是對的嗎? – christo8989

+0

不,它發生在您調用序列化或反序列化方法之前。 –

相關問題