繁体   English   中英

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

[英]WebAPI deserialization of a protected property is null

我的解决方案有一个 WebAPI 项目(.net core 3.1、Microsoft.AspNetCore.Mvc)和一个定义数据结构的(.Net Standard 2.1)class 库。 我的 Controller 发布了一个带有一个参数的帖子,该参数大部分正确地反序列化


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

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


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 在到达 controller 时始终为 null


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] 属性。 (目前是否有关于使用什么的最佳实践?)

If I read the Json from a file and use Newtonsoft.Json.JsonConvert.DeserializeObject it deserializes correctly with the Json attributes added, but still null in the controller.

如果我将其公开,它还会在 API 中正确反序列化,因此定价 class 本身似乎不是问题

发布后,我发现了这个关于将 Newtonsoft 设为默认值并在 Microsoft.AspNetCore.Mvc.NewtonsoftJson package 中使用MikeBeaton 接受的解决方案的问题,所以我将把它作为其他任何有此问题的人的一个潜在答案。 仍然想知道是否有更正确的解决方案可用。

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

正如文档所暗示的(强调我的)

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

I would guess that this was the design chosen because serializing an object is allowing that object to cross barriers of scope and the public scope is the only one that can reliably be assumed.

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM