c# - JSON.NET Deserialize interface to attribute name -


i have json string e.g.

{   "first_name": "paul"   "company": {     "company_name": "microsoft"   } } 

and class in following structure

[datacontract] class user {   [datamember(name = "first_name")]   public string firstname { get; set; }    [datamember(name = "company")]   public icompany company { get; set; } }  interface icompany {   string companyname { get; set; } }  [datacontract] class company : icompany {   [datamember(name = "company_name")]   public string companyname { get; set; } } 

i use custom auto resolver finds implementation of interface using autofac (pulled json.net website)

public class autofaccontractresolver : defaultcontractresolver     {         private readonly icontainer _container;          public autofaccontractresolver(icontainer container)         {             _container = container;         }          protected override jsonobjectcontract createobjectcontract(type objecttype)         {             jsonobjectcontract contract = base.createobjectcontract(objecttype);              // use autofac create types have been registered             if (_container.isregistered(objecttype))             {                 contract.defaultcreator = () => _container.resolve(objecttype);             }              return contract;         }     } 

i deserialize json string using

user user = jsonconvert.deserializeobject<user>(json, new jsonserializersettings                 {                     contractresolver = _resolver,                  }); 

now when deserialize json first_name gets serialized firstname property company_name not, returns null. when use tracewriter states cannot find member called company_name on icompany interface (which cannot set on company object class)

why json.net not using datamember name company object deserialize against? knows compmany object custom resolver , creates object no values inside.

how can use implementation of interface , not interface itself?

fyi, not whole object , cannot change property class instead of interface. slimmed down example of happening interface objects.

i had same problem , while searching answer found old question here. way asked got me on right track , solved problem. following works me:

i don't use autofac, pseudocode. should enough understand it:

public class autofaccontractresolver : defaultcontractresolver {     private readonly icontainer _container;      public autofaccontractresolver(icontainer container)     {         _container = container;     }      protected override jsonobjectcontract createobjectcontract(type objecttype)     {         jsonobjectcontract contract;          // use autofac create types have been registered         if (_container.isregistered(objecttype))         {             //get class mapped interface autofac             type mappedtype = _container.getmappedtypeforregisteredtype(objecttype);              //so example when objecttype contains 'icompany'             //then mappedtype should contain 'company'              //now use mappedtype create contract             contract = base.createobjectcontract(mappedtype);              //but still use objecttype resolving             contract.defaultcreator = () => _container.resolve(objecttype);         }         else             contract = base.createobjectcontract(objecttype);          return contract;     } } 

the contract should created using concrete implementation registered in dependency container instead of interface. resolving type container defaultcreator should still use interface.


Comments