JSON .NET在反序列化时拦截属性名称

时间:2014-03-25 17:55:45

标签: json.net json-deserialization

我正在使用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将包含&#34; FirstName&#34;只要。 如果客户发送:

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

Manifest hashset将包含&#34; FirstName&#34;和&#34;姓氏&#34;。

我尝试像这样实现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来获取来自客户端的所有属性,但后来我不知道如何创建&#34; objectType&#34;来自JObject的(C#DTO)。

2 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分:0)

您可以尝试使用不JObject.ToObject的{​​{1}}重载。在这种情况下,只要您没有使用JsonSerializer属性修饰DTO类,ToObject方法将使用不知道转换器的新序列化程序实例,这应该允许它工作。 / p>

[JsonConverter]

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