c# - 自定义转换器重写 ContractResolver

标签 c# json.net

我正在尝试使用自定义转换器修改对象类型,如here所述。 ,连同CamelCasePropertyNamesContractResolver .

所以转换器是这样的(这里什么也不做):

class MyJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsSubclassOf(typeof(MyType));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);
        t.WriteTo(writer);
    }
}

我这样使用它:

var jsonSerializationSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
jsonSerializationSettings.Converters.Add(new MyJsonConverter());
var camelCaseJsonOutput = await JsonConvert.SerializeObjectAsync(myObject, Formatting.None, jsonSerializationSettings);

但是序列化输出显示以大写开头的属性,因此似乎使用我的转换器以某种方式取消了驼峰式契约(Contract)解析器...

最佳答案

当你创建时

JToken t = JToken.FromObject(value);

它创建未格式化的原始 json。 所以,你可以用你自己的方式来控制它,camel、Pascal、wHaTeVeR。

例如:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    var myType = value as MyType;
    if (myType != null)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("myProperty");
        serializer.Serialize(writer, myType.myProperty); // Using this will allow to serialize inner values with CamelCasePropertyNamesContractResolver
        writer.WritePropertyName("Inner");
        serializer.Serialize(writer, myType.Inner);
      ...
        writer.WriteEndObject();
    }
}

对于使用驼峰命名法和附加属性序列化对象,我将采用这种方式(可能不是最有效的)

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteStartObject();

        writer.WritePropertyName("_custom_Prop_");
        writer.WriteValue("Custom Property value");

        WriteObjectProperties(writer, value);

        writer.WriteEndObject();
    }

    private static void WriteObjectProperties(JsonWriter writer, object value)
    {
        var myJsonWriter = new JTokenWriter();
        var js = new JsonSerializer();
        js.ContractResolver = new CamelCasePropertyNamesContractResolver();
        js.Serialize(myJsonWriter, value);
        var childTokens = myJsonWriter.Token.Children();
        foreach (var childToken in childTokens)
        {
            childToken.WriteTo(writer);
        }
    }

关于c# - 自定义转换器重写 ContractResolver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20063787/

相关文章:

c# - Xamarin XAML vs AXML vs Storyboard

c# - 如何允许匿名用户访问 MVC 中的某个给定页面?

c# - Umbraco - 如何在代码中访问内容蓝图(模板)

json - 如何获取Newtonsoft.Json反序列化值的未转义字符串值?

c# - 将包含对象列表的 JSON 响应反序列化为 C# 类

c# - 如何在 newtonsoft JSON 反序列化上接受单个属性的多个名称?

c# - 将 Json 数组解析为 C# 中的类

c# - 线程和单例

c# - 使用 Azure 地理冗余 (RA-GRS) 表存储时,如何更新 ASP.NET Core 中的 TableServiceClient 以指向辅助区域?

c# - 有没有办法在第一次运行时改进json反序列化?