【问题标题】:create custom json converter that masks sensitive information创建隐藏敏感信息的自定义 json 转换器
【发布时间】:2018-05-29 15:03:17
【问题描述】:

我正在编写一个自定义 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);
}

我在这里使用它:

    JsonSerializerSettings settings = new JsonSerializerSettings();
    settings.Converters.Add(new StudentJsonConverter());
    settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    var student = new Student { Name = "name", Phone = "1234" };

    var serializedString = JsonConvert.SerializeObject(student, settings);

    Console.WriteLine(serializedString);

但我总是得到一个空字符串。

【问题讨论】:

  • 如果不想序列化Phone字段,可以使用[JsonIgnore]属性。
  • 但如果它不为空,我想序列化它并屏蔽它。如果电话为空,那我就忽略它

标签: c# serialization json.net


【解决方案1】:

请查看Custom JsonConverter 示例。

编辑:

我认为最好在您的评论中针对另一个问题发布另一个问题,但无论如何,我已经玩了一段时间并得出了以下代码。我认为它比我之前发布的要好得多,所以我更喜欢删除我之前的示例。这段代码在我看来要好得多的原因是它不会改变您尝试序列化的 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));
}

【讨论】:

  • 这几乎可以工作。但是如果我要添加到我的 json 设置 settings.NullValueHandling = NullValueHandling.Ignore;并将属性 Name 设置为 null,该属性将被序列化。你知道如何解决这个问题吗?
  • 但是没有手动编写每个属性的方法吗?因为通过这样做,当我将属性添加到我的模型时,我将不得不更新转换器......
  • 您可以通过解析 JObject 的属性集合并对其进行操作来使代码更加动态;另一种选择是使用 NewtonSoft 属性(如 JsonIgnore 或其类似属性),或者甚至定义您自己的自定义属性并将它们应用到模型,然后在 WriteJson 方法中读取它们以决定做什么。无论如何,正如@Optional Option 所建议的那样,您可以简化很多,只需忽略一些属性。我真的认为序列化掩码属性而不是省略它们没有任何功能增益。
猜你喜欢
  • 2018-01-31
  • 2020-01-11
  • 2020-11-24
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
相关资源
最近更新 更多