【问题标题】:JSON .NET intercept property names on deserializationJSON .NET 在反序列化时拦截属性名称
【发布时间】:2014-03-26 07:52:48
【问题描述】:

我正在使用 WebAPI,它依赖于 JSON .NET 的 JSON 格式。在 C# 方面,我有一个如下所示的 DTO:

public class DTO1 : IManifestContainer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }        
    public HashSet<string> Manifest { get; private set; }
}
public interface IManifestContainer
{
    HashSet<string> Manifest { get; }
}

IManifestContainer 接口的想法是跟踪客户端在 JSON 对象中实际发送到服务器的属性。例如,如果客户端发送此 JSON:

{"FirstName":"Jojo"}

Manifest hashset 将仅包含“FirstName”。 如果客户端发送:

{"FirstName":"Jojo", "LastName":"Jones"}

Manifest 哈希集将包含“FirstName”和“LastName”。

我尝试像这样实现一个 JsonConverter:

public class ManifestJsonConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    if (reader.TokenType == JsonToken.Null)
    {
        return null;
    }

    JObject jObject = JObject.Load(reader);

    // Convert the JObject to a C# object?? 
    // Passing the serializer will call this method again
    object retVal = jObject.ToObject(objectType, serializer);

    IManifestContainer manifestContainer = (IManifestContainer) retVal;

    foreach (var jProperty in jObject.Properties())
    {
        manifestContainer.Manifest.Add(jProperty.Name);
    }
    return retVal;
}

public override bool CanConvert(Type objectType)
{
    return typeof (IManifestContainer).IsAssignableFrom(objectType);
}
}

我需要加载 JObject 以获取来自客户端的所有属性,但是我不知道如何从 JObject 创建“objectType”实例(C# DTO)。

【问题讨论】:

    标签: json.net json-deserialization


    【解决方案1】:

    在阅读this other post 之后,我想出了这个实现。这涵盖了所有情况。

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return null;
            }
    
            JObject jObject = JObject.Load(reader);
    
            JArray manifestArray = new JArray();
    
            foreach (var jProperty in jObject.Properties())
            {
                manifestArray.Add(jProperty.Name);
            }
    
            jObject["Manifest"] = manifestArray;
    
            var retVal = Activator.CreateInstance(objectType);
    
            serializer.Populate(jObject.CreateReader(), retVal);
    
            return retVal;
        }
    

    【讨论】:

      【解决方案2】:

      您可以尝试使用不带JsonSerializerJObject.ToObject 的重载。在这种情况下,ToObject 方法将使用一个不知道转换器的新序列化程序实例,只要您没有使用[JsonConverter] 属性修饰您的 DTO 类,它就应该允许它工作。

      object retVal = jObject.ToObject(objectType);
      

      如果这不起作用,您的另一个选择是手动创建 DTO 实例并通过反射填充它们的属性。

      【讨论】:

      • 我需要保留相同的序列化程序,因为它包含我在反序列化整个图形时必须保留的其他设置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      • 2013-04-01
      • 2022-01-01
      • 2021-06-11
      • 1970-01-01
      相关资源
      最近更新 更多