簡體   English   中英

Web API請求對象中的強類型AND任意屬性

[英]Strongly typed AND arbitrary properties in Web API request object

我有一個看起來很像這樣的對象:

public class MyNiceRequest 
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }

    public string SomeOptionalField { get; set; }
}

我的控制器看起來像下面的,仍然很標准:

public MyNiceResponse Post(MyNiceRequest request) {
...
}

從調用應用程序的前端,我想包括比對象中指定的三個更多的字段。 這些字段是在運行時生成的(通過管理界面控制),因此我無法將其應用於我的請求類。 但是,我還沒有找到在控制器中檢索它們的好方法。

我可以使我的請求對象( MyNiceRequest )從Dictionary<string,string>繼承-然后將它們全部獲取,但它們將不會綁定到強類型類的各自屬性上(似乎像Dictionary之前綁定了其余部分使用任何模型活頁夾)。 另外,更重要的是,驗證(對應用程序至關重要)將停止工作。

我已經看到了這個問題,但是它沒有給我任何東西,因為Request.Content.Read...方法給了我空的結果(因為它已經被讀取並綁定到模型了?)。

假設我要從前端輸入以下字段:

  • FirstName (應綁定到強類型,無其他地方)
  • LastName (應綁定到強類型,無其他地方)
  • SomeOptionalField (應綁定到強類型,無處可)
  • RuntimeGenerated1 (應該在字典中結束)
  • RuntimeGenerated2 (應該在字典中結束)

我想要以下兩種解決方案之一:

  • 可以從Dictionary<string,string>繼承,但是讓字典在強類型屬性之后綁定,以使驗證工作
  • MyNiceRequest上具有一個單獨的屬性,該屬性可能類似於Dictionary<string,string> TheRest { get; set; } Dictionary<string,string> TheRest { get; set; } Dictionary<string,string> TheRest { get; set; }並將其綁定到其余的傳入屬性。

重寫前端以將運行時生成的字段作為單獨的集合傳遞是不可行的。

..這是否可以通過重新使用/重新排序現有內容來實現,還是我必須從頭開始編寫完整的媒體類型格式化程序和/或模型綁定程序?

對於application/json內容類型,可以將DynamicObject與WebAPI的默認JSON格式化程序一起使用。

public class MyNiceRequest : DynamicObject
{
    private Dictionary<string, string> _dynamicMembers = new Dictionary<string, string>();

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; }

    public string SomeOptionalField { get; set; }

    [JsonIgnore]
    public Dictionary<string, string> DynamicMembers
    {
        get { return _dynamicMembers; }
    }

    public override bool TryGetMember(GetMemberBinder binder, out object value)
    {
        string stringValue;
        var isFound = _dynamicMembers.TryGetValue(binder.Name, out stringValue);
        value = stringValue;
        return isFound;
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (value is string)
        {
            _dynamicMembers[binder.Name] = (string)value;
            return true;
        }
        return false;
    }
}

編輯

  1. 如果希望對象以相同的格式序列化,請實現IDictionary<string, string> 這很簡單,只需將接口實現委派給_dynamicMembers

  2. 此解決方案不適用於默認的XML和x-www-form-urlencoded格式化程序:(

您可以擁有這樣的DTO。

public class MyNiceRequest
{
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }

    public string SomeOptionalField { get; set; }

    public Dictionary<string, string> TheRest { get; set; }
}

如果在請求正文中發布JSON,例如{"firstname":"arve", "therest":{"key":"value"}} ,則將填充FirstName屬性。 TheRest將具有一個帶有鍵“ key”和值“ value”的項目。 當然,由於JSON不包含LastName ,因此ModelState.IsValid將為false

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM