gpt4 book ai didi

c# - JSON.NET 将接口(interface)反序列化为属性名称

转载 作者:行者123 更新时间:2023-11-30 23:22:19 26 4
gpt4 key购买 nike

我有一个 JSON 字符串,例如

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

我的类(class)结构如下

[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 网站提取)找到接口(interface)的实现

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 接口(interface)上找不到名为 company_name 的成员(显然不能,因为它是在 Company 对象类上设置的)

为什么 JSON.NET 不使用 Company 对象中的 DataMember 名称进行反序列化?因为它知道来自自定义解析器的 Compmany 对象,所以它会创建该对象,但内部没有任何值。

如何让它使用接口(interface)的实现而不是接口(interface)本身?

仅供引用,这不是整个对象,我不能只将我的属性更改为类而不是接口(interface)。这只是所有接口(interface)对象所发生情况的精简示例。

最佳答案

我刚遇到同样的问题,在寻找答案时,我在这里找到了您的旧问题。实际上,你问它的方式让我走上了正确的轨道,我解决了问题。以下对我有用:

我不使用 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;
}
}

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

关于c# - JSON.NET 将接口(interface)反序列化为属性名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38834073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com