【问题标题】:Why BindNever attribute doesn't work为什么 BindNever 属性不起作用
【发布时间】:2017-02-16 17:48:06
【问题描述】:

我不想在我的CustomerViewModel 上绑定Id 属性,所以我添加了一个[BindNever] 属性,但它不起作用。有什么解决办法?

我有以下几点:

CustomerController.cs

// PUT api/customers/5
[HttpPut("{id}")]
public async Task<IActionResult> Put([FromUri] int id, [FromBody]CustomerViewModel customer)
{
  //Implementation
}

客户视图模型

public class CustomerViewModel
{
    [BindNever]
    public int Id { get; set; }
    public string LastName { get; set; }
    public string FirstName { get; set; }
    public string Email { get; set; }
}

如果我输入以下 json 。 id 属性仍然被绑定

{
  "id": 100,
  "lastName": "Bruce",
  "firstName": "Wayne",
  "email": "bruce@gothamcity.com"
}

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc model-binding


    【解决方案1】:

    这篇Blog post 读起来很有趣,并得出结论认为[FromBody] 注释“覆盖”了BindBehaviourAttributeBindNever 是一个简单的特化)。该模型由正文中可用的所有数据(在本例中为您的 JSON 数据)填充。

    我不认为这是直观的,issue 对此有很好的说明:

    [BindRequired] 自定义MVC模型绑定系统。这就是它 目的并按设计工作。

    [FromBody] 将受影响的属性或参数切换到 输入格式的不同世界。每个输入格式化程序(例如 Json.NET 和一个小型的 MVC 特定包装器)可以被认为是一个 具有自己定制的独立系统。模型绑定系统 不知道 JSON(或任何其他)反序列化的细节。

    经验教训:BindNever 在这种情况下不起作用。

    什么是替代品?

    解决方案 1:编写一些自定义模型绑定代码。我自己没有做过,但What is the correct way to create custom model binders in MVC6? 可能会有所帮助。

    解决方案 2:比较务实的解决方案

    也许这个简单(但不是很好)的解决方法可以帮助您:

    [HttpPut("{id}")]
    public async Task<IActionResult> Put([FromUri] int id, [FromBody]CustomerViewModel customer)
    {
        customer.Id = 0;
        //Implementation
    }
    

    【讨论】:

    • 拥有一个私人二传手似乎可以解决问题。我无法验证我的解决方案。我试着四处寻找类似的东西,但没有运气。
    【解决方案2】:

    我添加一个注释。

    现在微软正式解释了。

    https://docs.microsoft.com/ja-jp/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#attributes-for-complex-type-targets

    https://docs.microsoft.com/ja-jp/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#input-formatters

    https://docs.microsoft.com/ja-jp/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0#frombody-attribute

    总之,

    如果我们使用“FromBody 属性(包括 HttpPost 属性等默认值)”,它依赖于输入格式,BindNever 属性等将不起作用。

    相反,我们可以通过指定对应于输入格式化程序的属性来做到这一点。 例如,对于默认的 json 可以使用“System.Text.Json.Serialization.JsonIgnoreAttribute”忽略它。

    【讨论】:

      【解决方案3】:

      你也可以这样做

      public class CustomerViewModel
      {
          public int Id { get; private set; }
          public string LastName { get; set; }
          public string FirstName { get; set; }
          public string Email { get; set; }
      }
      

      【讨论】:

        【解决方案4】:

        试试NotMapped 属性。

        正文必须至少为 30 个字符;你输入了 24。

        【讨论】:

          猜你喜欢
          • 2019-02-19
          • 1970-01-01
          • 2021-04-27
          • 2019-04-04
          • 1970-01-01
          • 1970-01-01
          • 2016-07-05
          • 2011-03-24
          • 1970-01-01
          相关资源
          最近更新 更多