簡體   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