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; }
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
?
source share