1+ using Newtonsoft . Json ;
2+ using System ;
3+ using System . Collections . Generic ;
4+ using System . Reflection ;
5+ using System . Text ;
6+
7+ namespace Enum . Ext . Converter
8+ {
9+ public class JsonTypeSafeEnumConverter : JsonConverter
10+ {
11+ public override bool CanConvert ( Type objectType )
12+ {
13+ Type currentType = objectType . BaseType ;
14+ while ( currentType != typeof ( object ) )
15+ {
16+ if ( currentType . IsGenericType && currentType . GetGenericTypeDefinition ( ) == typeof ( TypeSafeEnum < , > ) )
17+ return true ;
18+
19+ currentType = currentType . BaseType ;
20+ }
21+
22+ return false ;
23+ }
24+
25+ private Type GetKeyType ( Type objectType )
26+ {
27+ Type currentType = objectType . BaseType ;
28+ while ( currentType != typeof ( object ) )
29+ {
30+ if ( currentType . IsGenericType && currentType . GetGenericTypeDefinition ( ) == typeof ( TypeSafeEnum < , > ) )
31+ return currentType . GenericTypeArguments [ 1 ] ;
32+
33+ currentType = currentType . BaseType ;
34+ }
35+
36+ return null ;
37+ }
38+
39+ private MethodInfo GetBaseMethod ( Type objectType )
40+ {
41+ Type currentType = objectType . BaseType ;
42+ while ( currentType != typeof ( object ) )
43+ {
44+ if ( currentType . IsGenericType && currentType . GetGenericTypeDefinition ( ) == typeof ( TypeSafeEnum < , > ) )
45+ return currentType . GetMethod ( "GetById" ) ;
46+
47+ currentType = currentType . BaseType ;
48+ }
49+
50+ return null ;
51+ }
52+
53+ public override object ReadJson ( JsonReader reader , Type objectType , object existingValue , JsonSerializer serializer )
54+ {
55+ if ( ! CanConvert ( objectType ) )
56+ {
57+ throw new NotImplementedException ( ) ;
58+ }
59+
60+ var keyType = GetKeyType ( objectType ) ;
61+ var method = GetBaseMethod ( objectType ) ;
62+
63+ return method . Invoke ( null , new [ ] { Convert . ChangeType ( reader . Value , keyType ) } ) ;
64+ }
65+
66+ public override void WriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
67+ {
68+ var idProperty = value . GetType ( ) . GetProperty ( "Id" ) ;
69+
70+ var ser = new JsonSerializer ( ) ;
71+ ser . Serialize ( writer , idProperty . GetValue ( value ) ) ;
72+ }
73+
74+ public override bool CanRead => true ;
75+ }
76+ }
0 commit comments