Json.Net 库支持通过反射设置具有私有集的字段,因此这两个选项都工作得很好:
public class Abc1
{
public int Id { get; set; }
public string Title { get; set; }
}
public class Abc2
{
public Abc2(int id, string title)
{
Id = id;
Title = title;
}
public int Id { get; private set; }
public string Title { get; private set; }
}
void Main()
{
var request = new Abc1 { Id = 1, Title = "Test" };
Execute(request);
var request = new Abc2(1, "Test");
Execute(request);
}
private void Execute<T>(T request)
{
var requestSerialized = JsonConvert.SerializeObject(request);
var deserialized = JsonConvert.DeserializeObject<T>(requestSerialized);
request.Dump();
requestSerialized.Dump();
deserialized.Dump();
}
然而,尽管从 1.0 版到 2.2 版的 asp.net 核心已将 json.net 内置为常规 json 处理程序,但无法在控制器中使用没有默认构造函数的类:
[HttpPost]
public async Task<object> Update([FromBody] City.Update.Command command, CancellationToken cancellationToken)
{
var result = await this.Mediator.Send(command, cancellationToken);
return result;
}
如果Command 没有默认构造函数,而只有一个私有 set,我们将得到 null,字段不会被设置。
为什么会这样,如何纠正?
services.AddMvc().AddNewtonsoftJson();
但是我还没有测试过beta。
团队:
using MediatR;
namespace Application.City.Update
{
public class Command : IRequest<CityData>
{
public Command(CityData city)
{
this.City = city;
}
public CityData City { get; private set; }
}
public class CityData
{
public CityData()
{
}
public CityData(City city)
{
this.Id = city.Id;
this.Title = city.Title;
}
public int Id { get; set; }
public string Title { get; set; }
public City ToEntity()
{
return new City
{
Id = this.Id,
Title = this.Title,
};
}
}
}
如果有任何东西是对问题的回答,而不是对答案的补充。:)
总的来说,我似乎对 Json.Net 如何处理私有集的确切含义没有完全准确的理解。原则上,他会这样做,是的,但是一旦涉及复合对象,细微差别就开始了。
这是一个比问题更扩展的示例:
虽然一切正常:
但是,如果您更改 DataDto2 类上的复合属性的定义,则不会设置它:
类似地,如果您在类的顶层声明一个私有集,那么链上的所有内容都将为空。
同时,顶层的原始类型根本不会对更改字段的可见性做出反应。
总的来说,考虑到我的 CityData 是一个扁平的 Dto,它总是只包含原始类型(int、string、DateTime),你可以按如下方式获取:
然后可以使命令完全 get only:
对于 CityData,删除构造函数并将所有字段放入私有集中:
更新。或者
如果你设置了属性,那么序列化会再次被选中:
Update2 感谢@PavelMayorov 为该问题提供了另一个很好的解决方案
[JsonConstructorAttribute]:(文档)Update3 感谢@Grundy 的帮助,他第一个指出上面的代码应该反序列化。实际上,问题中的示例不是我正在运行的代码的精确副本,并且视图很模糊,我没有考虑最终影响不同答案的微小差异。