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
Post a Comment