我如何限制NewtonSoft.JSON来序列化接口



非常简单的例子(我在单元测试中使用它):

    private interface ISampleSubset
    {
        int id { get; }
    }
    private class Sample : ISampleSubset
    {
        public int id { get; set; }
        public string name { get; set; }
    }

下面是一个关于NewtonSoft JSON Serialize的小包装:

public string Serialize<T>(T t)
{
        using (var sw = new StringWriter())
        {
            using (var jw = new JsonTextWriter(sw))
            {
                var js = JsonSerializer.Create();
                js.Serialize(jw, t);
                jw.Flush();
            }
            return sw.GetStringBuilder().ToString();
        }
}

现在我想序列化ISampleSubset:然后这样命名:

ISampleSubSet t = new Sample()
{
    id = 1,
    name = "joe"
};
string json = Serialize(t);
我期望得到
{"id":1}
但我得到的却是
{"id":1,"name":"joe"}

我猜是js。Serialize使用反射来"查看"接口外部对象的其他属性。如何将其限制在界面上的那些属性?

序列化器甚至不知道你的接口,所以它给你所有的东西——它接受一个object,所以它不知道你已经声明了ISampleSubset类型的变量——它只知道对象本身是Sample的一个实例。

可能不是最好的解决方案,但是您可以使用JsonConverter来限制出现在序列化对象中的属性。

这段代码可能非常低效——请不要评判——只是把它放在一起,你可以清理细节并实现你需要的任何东西:

public class MyConverter<T> : JsonConverter {
    private readonly string[] _propertyNames;
    public MyConverter() {
        _propertyNames = typeof(T).GetProperties().Select(p => p.Name).ToArray();
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        var objectType = value.GetType();
        var newObject = new Dictionary<string, object>();
        foreach (string propName in _propertyNames) {
            var prop = objectType.GetProperty(propName);
            if (prop != null) {
                newObject[propName] = prop.GetValue(value, null);
            }
        }
        string s = JsonConvert.SerializeObject(newObject);
        writer.WriteRaw(s);
    }
    public override bool CanConvert(Type objectType) {
        return true; // ?
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        throw new NotImplementedException();
    }
}
public static string Serialize<T>(T t) {
    return JsonConvert.SerializeObject(t, new MyConverter<T>());
}

基本上它所做的是使用接口类型上的反射来检索其属性,然后仅使用在接口上找到的属性创建字典(您可以通过多种方式做到这一点)-然后使用简单的JsonConvert类来序列化字典。

NewtonSoft。JSON根据默认规则(在。net 3.5 IIRC中)序列化你创建的对象实例,默认情况下,对象的所有属性都是可序列化的。如果你将变量声明为接口类型并不重要,因为它可能通过反射来进行序列化。

如果你想限制被序列化的属性,最好的方法是使用nonserialized属性

相关内容

  • 没有找到相关文章

最新更新