C# 创建屏蔽敏感信息的自定义json转换器

C# 创建屏蔽敏感信息的自定义json转换器,c#,serialization,json.net,C#,Serialization,Json.net,我正在编写一个自定义json转换器,它将序列化一个对象并屏蔽包含一些敏感信息的某些字段。我已经创建了转换器,但是当我使用转换器序列化对象时,得到的是一个空字符串。有人能告诉我我做错了什么吗 public class Student { public string Name { get; set; } public string Phone { get; set; } } class StudentJsonConverter : JsonConverter { ///

我正在编写一个自定义json转换器,它将序列化一个对象并屏蔽包含一些敏感信息的某些字段。我已经创建了转换器,但是当我使用转换器序列化对象时,得到的是一个空字符串。有人能告诉我我做错了什么吗

public class Student
{
    public string Name { get; set; }

    public string Phone { get; set; }
}

class StudentJsonConverter : JsonConverter
{
    /// <inheritdoc />
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value is Student student)
        {
            student.Phone = MaskString(student.Phone);
        }

        writer.WriteStartObject();
        serializer.Serialize(writer, value);
        writer.WriteEndObject();
    }

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

    /// <inheritdoc />
    public override bool CanConvert(Type objectType) => typeof(Student) == objectType;

    private static string MaskString(string sensitiveInformation) => string.IsNullOrWhiteSpace(sensitiveInformation) ? null : new string('*', sensitiveInformation.Length);
}
但是我总是得到一个空字符串。

请看一下示例

编辑:

我认为最好在你的评论中针对另一个问题发布另一个问题,但无论如何,我已经玩了一点,并给出了以下代码。我认为这比我以前发布的要好得多,所以我更喜欢删除我以前的示例。我觉得这段代码好得多的原因是它不会改变您试图序列化的Student对象,而只是在JObject实例上工作

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    Newtonsoft.Json.Linq.JToken t = Newtonsoft.Json.Linq.JToken.FromObject(value);
    JObject jo = (JObject)t;
    if (value is Student)
    {
        jo["Phone"] = MaskString(jo.Value<string>("Phone"));

        if (String.IsNullOrEmpty(jo.Value<string>("Name")))
        {
            jo.Remove("Name");
        }
    }
    serializer.Serialize(writer, jo, typeof(Student));
}
public override void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
Newtonsoft.Json.Linq.JToken t=Newtonsoft.Json.Linq.JToken.FromObject(值);
JObject jo=(JObject)t;
如果(值为学生)
{
jo[“Phone”]=MaskString(jo.Value(“Phone”);
if(String.IsNullOrEmpty(jo.Value(“Name”))
{
删除(“名称”);
}
}
序列化(writer,jo,typeof(Student));
}

这几乎奏效了。但是如果我在json设置中添加。NullValueHandling=NullValueHandling.Ignore;并将属性名称设置为null,则此属性将被序列化。您知道如何修复此问题吗?但是否有一种方法可以在不手动写入每个属性的情况下修复此问题?因为这样做,当我将一个属性添加到我的模型中时,我必须更新转换器…通过解析JObject的properties集合并对其进行操作,可以使代码更加动态;另一种选择是使用NewtonSoft属性(如JsonIgnore或其类似项),甚至定义自己的自定义属性并将其应用于模型,然后在WriteJson方法中读取它们以决定要做什么。无论如何,正如@Optional所建议的,您可以简化很多,只需忽略一些属性。我认为序列化屏蔽属性比忽略它们在功能上没有什么好处。如果您不想序列化Phone字段,那么您可以使用[JsonIgnore]属性。但我想序列化它,并在它不为null时屏蔽它。如果电话是空的,那么我将忽略它
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    Newtonsoft.Json.Linq.JToken t = Newtonsoft.Json.Linq.JToken.FromObject(value);
    JObject jo = (JObject)t;
    if (value is Student)
    {
        jo["Phone"] = MaskString(jo.Value<string>("Phone"));

        if (String.IsNullOrEmpty(jo.Value<string>("Name")))
        {
            jo.Remove("Name");
        }
    }
    serializer.Serialize(writer, jo, typeof(Student));
}