2016-08-08 54 views
2

我有一个JSON字符串,例如JSON.NET反序列化属性名称的接口

{ 
    "first_name": "Paul" 
    "company": { 
    "company_name": "Microsoft" 
    } 
} 

和我的课是在下面的结构

[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; } 
} 

我使用自定义的自动解析刚刚发现使用autofac一个接口的实现(从json.net网站拉)

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 to create types that have been registered with it 
      if (_container.IsRegistered(objectType)) 
      { 
       contract.DefaultCreator =() => _container.Resolve(objectType); 
      } 

      return contract; 
     } 
    } 

然后我使用反序列化json字符串使用

User user = JsonConvert.DeserializeObject<User>(json, new JsonSerializerSettings 
       { 
        ContractResolver = _resolver, 

       }); 

现在,当我反序列化json时,first_name被序列化为FirstName属性,但是company_name没有,它只是返回null。当我使用TraceWriter时,它指出它无法在ICompany接口上找到名为company_name的成员(显然它不能在公司对象类中设置)

为什么JSON.NET不使用DataMember名称公司反对反序列化?因为它知道来自自定义解析器的Compmany对象,并且它创建了该对象,但没有内部值。

我怎样才能得到它使用接口的实现而不是接口本身?

仅供参考,这不是整个对象,我不能只是将我的属性更改为类而不是接口。这仅仅是所有界面对象发生变化的简单例子。

回答

2

我刚刚遇到同样的问题,在寻找答案时,我在这里发现了您的旧问题。其实你问的方式让我走上了正轨,我解决了这个问题。以下适用于我:

我不使用Autofac,所以这是伪代码。但它应该足以理解它:

public class AutofacContractResolver : DefaultContractResolver 
{ 
    private readonly IContainer _container; 

    public AutofacContractResolver(IContainer container) 
    { 
     _container = container; 
    } 

    protected override JsonObjectContract CreateObjectContract(Type objectType) 
    { 
     JsonObjectContract contract; 

     // use Autofac to create types that have been registered with it 
     if (_container.IsRegistered(objectType)) 
     { 
      //get the class that is mapped to the interface from autofac 
      Type mappedType = _container.GetMappedTypeForRegisteredType(objectType); 

      //so for example when objectType now contains 'ICompany' 
      //then mappedType now should contain 'Company' 

      //now use the mappedType to create the contract 
      contract = base.CreateObjectContract(mappedType); 

      //but still use the objectType for resolving 
      contract.DefaultCreator =() => _container.Resolve(objectType); 
     } 
     else 
      contract = base.CreateObjectContract(objectType); 

     return contract; 
    } 
} 

合同应该使用在依赖容器而不是接口中注册的具体实现来创建。 从DefaultCreator的容器中解析类型显然应该仍然使用该接口。

相关问题