How to find out if a type can be converted using Json.NET?

I am trying to write an interface for a collection that internally stores data as a JObject

 internal class JsonDataSet : IDataSet { private JObject Document { get; set; } // The following methods are from the IDataSet interface public int Count { ... } public void Add<T>(string key, T value) { ... } public T GetItem<T>(string key) { ... } public bool ContainsKey(string key) { ... } } 

In the Add<T> method, I want to provide a useful exception if the user type does not have a DataContract annotation. For example, if someone calls:

 dataSet.Add<IDictionary<string, IList<CustomType>>>(dict); 

it throws an exception "Cannot serialize type 'CustomType'. DataContract annotations not found." if CustomType has no corresponding annotation.

So far, I have found a way to get every common argument in a type definition so that I can check them out:

 private IEnumerable<Type> GetGenericArgumentsRecursively(Type type) { if (!type.IsGenericType) yield return type; foreach (var genericArg in type.GetGenericArguments()) foreach (var yieldType in GetGenericArgumentsRecursively(genericArg )) yield return yieldType; } 

and tried to implement an add method like this:

 public void Add<T>(string key, T value) { foreach(var type in GetGenericArgumentsRecursively(typeof(T))) { if(!type.IsPrimitive && !Attribute.IsDefined(type, typeof(DataContractAttribute))) throw new Exception("Cannot serialize type '{0}'. DataContract annotations not found.", typeof(T)); } Document.Add(new JProperty(key, JToken.Parse(JsonConvert.SerializeObject(value)))); } 

I think this will work for primitive types and custom types, but not for non-generic .NET types, since they do not have all DataContract annotations. Is there a way to find out what types can be serialized using JsonConvert ?

+4
source share
1 answer

Json.NET supports almost all types, even those that do not have any user attributes. Among the supported attributes are DataContract, JsonObject, Serializable. There are many ways to get Json.NET to include a member in serialization and many to skip it. If you cannot serialize some class, this is more likely due to problems other than the absence of Data * attributes: members throw exceptions, missing constructors, faulty converters, visibility problems, etc. Your error messages are unlikely to be more useful than those provided by Json.NET.

You will need to replicate the crazy sums of logic from Json.NET if you want to test in advance. It is not enough to check the type and attributes of an element. Just checking the converter used for the property will require checking at least five places. And even if you do all this work, it will not be enough, because in the new version in Json.NET a new type or converter or function or attribute will be introduced, and you will have to repeat all this again.

The only reliable way to test a type type can be serialized to try to serialize it.

+6
source

Source: https://habr.com/ru/post/1501379/


All Articles