Krótka odpowiedź na to pytanie to: automatyczne sprawdzenie pod kątem numeru ShouldDeserialize{PropertyName}()
nie jest obecnie zaimplementowane, mimo że jest to ShouldSerialize{PropertyName}()
. Dłuższą odpowiedź i obejście tego problemu.
Klasa jest używana wewnętrznie przez Json.NET do zdefiniowania umowy dotyczącej mapowania właściwości JSON na składnik .NET lub parametr konstruktora. Ma dwie właściwości predykatu: ShouldSerialize
i ShouldDeserialize
, które, gdy nie są zerowe, uniemożliwiają odpowiednio serializację i deserializację właściwości. Inicjowanie każdego JsonProperty
jest zadaniem urządzenia ContractResolver
. Dla każdej właściwości {PropertyName}
Json.NET-a default contract resolver automatycznie sprawdza obecność metody public bool ShouldSerialize{PropertyName}()
. Jeśli taka metoda istnieje, dodaje do niej wywołanie w predykacie ShouldSerialize
, tym samym tłumiąc serializację, gdy metoda zwraca false
. Zostało to zaimplementowane, ponieważ kontrolowanie serializacji właściwości za pomocą metody ShouldSerialize{PropertyName}()
jest standardowym wzorcem obsługiwanym np. Przez XmlSerializer
. Aby uzyskać więcej informacji, zapoznaj się z odpowiednią wersją Json.NET release notes.
Na przykład w poniższej klasie serializacji MyObjectData
będą tłumione chyba MyObjectData.Count > 0
:
class MyObject
{
public DataDictionary MyObjectData { get; set; }
public bool ShouldSerializeMyObjectData() { return MyObjectData != null && MyObjectData.Count > 0; }
}
JsonProperty.ShouldDeserialize
jednak to nigdy nie jest ustawiony przez domyślną zamówienia rezolwerem. Może to wynikać z faktu, że nie ma standardowego wzorca do deserializacji równoważnego ShouldSerialize{PropertyName}()
, a więc Newtonsoft nigdy nie miał żadnych żądań wprowadzenia takiego wzoru. Niemniej jednak, jak już zauważyłeś, infrastruktura obsługująca taki wzorzec istnieje, a więc aplikacje mogą tworzyć custom contract resolvers, które właśnie to robią. W rzeczywistości, Json.NET ma przykład takiego rezolwerem kontraktu w swoim własnym test suite:
public class ShouldDeserializeContractResolver : DefaultContractResolver
{
public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name);
if (shouldDeserializeMethodInfo != null)
{
property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o, null); };
}
return property;
}
}
public class ShouldDeserializeTestClass
{
[JsonExtensionData]
public IDictionary<string, JToken> ExtensionData { get; set; }
public bool HasName { get; set; }
public string Name { get; set; }
public bool ShouldDeserializeName()
{
return HasName;
}
}
Jeśli chcesz warunkowo tłumić deserializacji właściwości nawet gdy są obecne w JSON, można rozważyć użycie (a caching) ten resolver umowy.
Nie mówi nic o 'ShouldDeserialize' w [documentation] (http://www.newtonsoft.com/json/help/html/ConditionalProperties.htm). Dlaczego chcesz serializować coś, ale nie deserializować go? – kjbartel
@kjbartel Ten sam model do serializacji/deserializacji, ale przy deserializacji istnieje link intermediarly (hateoas) do uzyskiwania dostępu do tej konkretnej właściwości. –
Zobacz także [Serialize Property, ale nie Deserialize Property w Json.Net] (http: // stackoverflow.com/q/31731320/10263) –