2012-11-28 14 views
5

Vedo che utilizzando JSON.Net, posso decodificare oggetti polimorfici se un attributo $type specifica il tipo specifico dell'oggetto JSON. In tutti gli esempi che ho visto, $type include lo spazio dei nomi. È possibile fare questo lavoro includendo solo un nome di tipo semplice senza l'assembly? Sarei felice di specificare un assembly predefinito su JsonSerializer se è possibile.JSON.Net: deserializzazione di tipi polimorfici senza specificare il gruppo

sono in grado di deserializzare il JSON utilizzando:

public class SingleAssemblyJsonTypeBinder : SerializationBinder 
{ 
    private readonly Assembly _assembly; 
    private Dictionary<string, Type> _typesBySimpleName = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase); 
    private Dictionary<Type,string> _simpleNameByType = new Dictionary<Type, string>(); 

    public SingleAssemblyJsonTypeBinder(Assembly assembly) 
    { 
     _assembly = assembly; 
     _typesBySimpleName = new Dictionary<string, Type>(); 

     foreach (var type in _assembly.GetTypes().Where(t => t.IsPublic)) 
     { 
      if (_typesBySimpleName.ContainsKey(type.Name)) 
       throw new InvalidOperationException("Cannot user PolymorphicBinder on a namespace where multiple public types have same name."); 

      _typesBySimpleName[type.Name] = type; 
      _simpleNameByType[type] = type.Name; 
     } 
    } 

    public override Type BindToType(string assemblyName, string typeName) 
    { 
     Type result; 
     if (_typesBySimpleName.TryGetValue(typeName.Trim(), out result)) 
      return result; 

     return null; 
    } 

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName) 
    { 
     string name; 

     if (_simpleNameByType.TryGetValue(serializedType, out name)) 
     { 
      typeName = name; 
      assemblyName = null;// _assembly.FullName; 
     } 
     else 
     { 
      typeName = null; 
      assemblyName = null; 
     } 
    } 
} 

...

public static JsonSerializerSettings GetJsonSerializationSettings() 
{ 
    var settings = new JsonSerializerSettings(); 
    settings.Binder = new SingleAssemblyJsonTypeBinder(typeof(MvcApplication).Assembly); 
    settings.TypeNameHandling = TypeNameHandling.Objects; 
    return settings; 
} 

...

var serializer = JsonSerializer.Create(settings); 

non sono stato in grado di fare questo lavoro con MVC però. Sto configurando la deserializzazione JSON per il codice sottostante in Application_Start e l'oggetto è deserializzato, ma usando il tipo base uno.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Binder = new SingleAssemblyJsonTypeBinder(this.GetType().Assembly); 
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.All; 
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; 

risposta

9

Crea una derivata SerializationBinder in cui esclusione BindToName e Set out string assemblyName è null (Edit: o il nome di montaggio di default) e out string typeName al tuo strisce nome di tipo

Impostare il legante al JsonSerializerSettings.Binder prima di serializzazione .

Fammi sapere se questo non funziona

+0

JsonSerializerSettings.Binder è ora deprecato. – Theyouthis

Problemi correlati