2016-12-16 83 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

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

相关问题