【问题标题】:Can I get the attributes on a property from the WriteJson method of a custom JsonConverter?我可以从自定义 JsonConverter 的 WriteJson 方法获取属性的属性吗?
【发布时间】:2014-06-26 12:14:11
【问题描述】:

我想用自定义属性装饰我的类,并在我使用自定义 JsonConverter 中的 json.net 转换为 json 时读取它们。然后我会根据这个自定义属性改变序列化。

public class MyCustomJsonConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        //I want to get any attributes set on the property here.
    }

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

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Int64);
    }
}

另一种方法是使用属性在属性上指定我的自定义 JsonConverter,但我不想这样做,因为我想通过在 JsonSerializer 设置中实例化转换器将一些行为注入到我的自定义 JsonConverter 的构造函数中如下。

String json = JsonConvert.SerializeObject(new MyCLass(), new JsonSerializerSettings { 转换器 = 新列表 { 新的 MyCustomJsonConverter() } });

我可以在 textWriter 路径中找到属性的名称。而且我可以在有关元数据的文档中看到一些有趣的提示,但我找不到这样做的方法。

这是一个装饰类示例:

public class MyCustomAttribute : Attribute { }
public class MyCLass
{
    [MyCustom]
    public Int64 MyInt { get; set; }
}

【问题讨论】:

  • 如果你能得到属性的名字,你也得到了那个属性的一个PropertyInfo对象吧?只需使用 PropertyInfo.GetCustomAttributes(...) 这将为您提供与相应属性关联的自定义属性...
  • 你能发布一个用自定义属性装饰的类的例子吗?
  • 埃尔贡佐。不幸的是,我不知道获取 PropertyInfo 的方法——如果可以的话,那就太好了。我只有来自 textWriter.Path 的属性名称。我也没有类型或类型的名称。
  • 利哈。当然,我已经添加了一个示例。我现在正在试验;我没有一个真实的例子,所以我编了一个。

标签: c# .net serialization attributes json.net


【解决方案1】:

JsonConverters 适用于类型,而不适用于字段或属性。

与其为使用现有类型的属性添加属性,不如考虑创建一个新类型并为其编写转换。

public struct MyCustomType
{
    ...
}

public class MyClass
{
    public MyCustomType {get; set;}
}

此外,您还想以什么其他方式序列化原始整数?如果整数代表某物,则为该物创建一个结构或类。

另请参阅:"ValueObject"(领域驱动设计基本概念)

根据您在下面的评论,另一种方法是忘记 JsonConverters 并简单地公开辅助属性:

public class MyClass
{
    [JsonIgnore]
    public Int64 MyInt {get; set;}

    [JsonProperty("MyInt")]
    public Int64 MyEncryptedInt
    {
        get { return Encrypt(MyInt); }
        set { MyInt = Decrypt(value); }
    }
}

【讨论】:

  • 谢谢,我需要更改所有其他代码才能理解新的值类型,但我认为这可能更好。为什么?因为有时对于这个特定的整数,我想在它往返客户端时对其进行加密。
  • 如果是简单加密,您可以考虑另一种方法,如我上面的编辑所示。
最近更新 更多