受保护属性的WebAPI反序列化为null



我的解决方案有一个WebAPI项目(.net core 3.1,Microsoft.AspNetCore.Mvc(和一个定义数据结构的(.net Standard 2.1(类库。我的控制器发布了一个带有单个参数的帖子,该参数基本上正确地反序列化


public class apiRequest
{
public RequestData TheData { get; set; }
public Options Options { get; set; }
public apiRequest() { }
}

RequestData和子对象在.Net Standard 2.1类库中定义,并通过nuget包添加


public class RequestData : IRequestData
{
public int Datum{ get; set; }
...
public List<ComplexItem> ComplexItems { get; set; }
...
}
public class ComplexItem: ItemBase, IComplexItem
{
public ComplexItem() : base() { }
public ComplexItem(Pricing defaultPricing) : base(defaultPricing) { }
[JsonConstructor]
public ComplexItem(Pricing defaultPricing, Pricing selectedPricing) : base(defaultPricing, selectedPricing) { }
}

我遇到的问题是defaultPricing在到达控制器时总是为空


public class ItemBase : IItemBase
{
public ItemBase () { }
public ItemBase (Pricing defaultPricing)
{
DefaultPricing = defaultPricing;
}
[JsonConstructor]
public ItemBase (Pricing defaultPricing, Pricing selectedPricing)
{
DefaultPricing = defaultPricing;
SelectedPricing = selectedPricing;
}
#region Pricing
[JsonProperty]
protected Pricing DefaultPricing { get; set; }
public Pricing SelectedPricing { get; set; }
[JsonIgnore]
protected Pricing CurrentPricing
{
get { return SelectedPricing ?? DefaultPricing; }
set { SelectedPricing = value; }
}
[JsonIgnore]
public decimal Cost { get => CurrentPricing?.Cost ?? 0; }
[JsonIgnore]
public decimal Price { get => CurrentPricing?.Price ?? 0; }
#endregion
}

我尝试过使用[DataContract]和[DataMember]属性、JsonObject、JsonConstructor、JsonProperty属性和[Serializable]属性。(目前是否有关于使用什么的最佳实践?(

如果我从文件中读取Json并使用Newtonsoft.Json.JsonConvert.DeserializeObject,它会正确地反序列化,并添加Json属性,但在控制器中仍然为null。

如果我将其公开,它也会在API中正确地反序列化,因此它在Pricing类本身中似乎不会出现问题

发帖后,我发现这个问题是关于将Newtonsoft设为默认值,并在那里使用MikeBeaton公认的解决方案和Microsoft.AspNetCore.Mvc.NewtonsoftJson包,所以我将把它作为其他有这个问题的人的一个潜在答案。我仍然想知道是否有更正确的解决方案。

System.Text.Json序列化公共属性

正如文件所暗示的(强调矿(

默认情况下,所有(只读(公共属性都被序列化。可以指定要排除的特性。

我想这是选择的设计,因为序列化对象可以让该对象跨越范围的障碍,而公共范围是唯一可以可靠假设的范围。

如果你仔细想想,这是有道理的。比方说,定义一个protected属性并序列化对象。然后,客户端将其拾取并将该文本表示反序列化为public属性。您所设计的派生类型的实现细节现在可以在修饰符定义的范围之外访问。

除了简单地指出你自己的答案,Newtonsoft允许这个受保护的属性被序列化之外,我建议你更仔细地研究你的设计,以及为什么这些属性首先受到保护。这在API实现的上下文中是有意义的,但不能(不应该(假设客户端遵循相同的继承结构(或者根本支持继承(。似乎您可能想要定义一个真正的DTO来充当API响应的"形状",并使用protected范围来控制访问和可以跨越API边界的DTO,找到从内部类型转换的正确位置。

最新更新