3

非常に単純な例 (私は単体テストでこれを使用しています):

    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がリフレクションを使用して、インターフェースの「外側」のオブジェクトの他のプロパティを「見る」と推測しています。インターフェイスのこれらのプロパティだけに制限するにはどうすればよいですか?

4

2 に答える 2

4

シリアライザーはあなたのインターフェースについてさえ知らないので、あなたにすべてを与えてobjectISampleSubsetますSample.

おそらく最善の解決策ではありませんが、 a を使用し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クラスを使用して辞書をシリアル化します。

于 2013-05-24T15:10:30.400 に答える
1

NewtonSoft.JSON は、オブジェクトのすべてのプロパティが既定でシリアル化可能であるという既定の規則 (.NET 3.5 IIRC 以降) に基づいて、作成したオブジェクト インスタンスをシリアル化します。おそらくリフレクションによってシリアル化を行っているため、変数をインターフェイス型として宣言したかどうかは問題ではありません。

シリアル化されるプロパティを制限する場合、最善の方法はNonSerialized属性を使用することです。

于 2013-05-24T14:56:06.937 に答える