混合Bind和FromBody属性MVC 6

时间:2016-03-02 12:48:23

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

我有以下控制器操作

[HttpPut("{id}")]
public void Put(int id, [Bind("BirthDate")][FromBody]ExpandoObject value)
{
   _dataContext.Update(value);
}

我试图限制允许的属性,我认为这会起作用,但是,它没有和值接收所有发送的值而不仅仅是BirthDate - 我不想使用视图模型因为我想要要发送的动态对象。仅供参考,这对普通模型对象也不起作用。

这是我要求身体发送的json

{
      "FirstName": "Lionell",
      "LastName": "Messi",
      "BirthDate": "2009-04-06T11:54:29.047",
      "PhoneNumber": "1234567890",
      "EmailAddress": "blabla@gmail.com",
      "SchoolId": 1,
      "IsIndependent": true
}

1 个答案:

答案 0 :(得分:0)

阅读完源代码后,在请求正文中发布json时,会使用BodyModelBinder。不幸的是,这个模型绑定器似乎并不像IPropertyBindingPredicateProvider属性那样应用[Bind]实例提供的PropertyFilters。

它只是使用JsonInputFormatter将json反序列化为模型类型:

var formatters = bindingContext.OperationBindingContext.InputFormatters;
var formatter = formatters.FirstOrDefault(f => f.CanRead(formatterContext));

...

try
{
    var previousCount = bindingContext.ModelState.ErrorCount;
    var result = await formatter.ReadAsync(formatterContext);
    var model = result.Model;

这对我来说似乎是个错误......

与此同时,您可以尝试评估一些可用的选项。如the docs中所述,我们知道格式化程序使用Json.Net:

  

JsonInputFormatter是默认的格式化程序,它基于   Json.NET。

基本上你需要遵循一种方法来排除与Json.Net一起使用的属性,比如使用[JsonIgnore]属性。 (或者只使用一些不包含这些属性的DTO对象:))

当然在你的情况下更难,因为你有一个动态对象而不是强类型对象,这意味着:

  1. 您没有类型可以应用属性
  2. Json.net将不知道您在控制器操作中设置的任何属性。
  3. 您可以探索更新JsonSerializerSettings,例如尝试使用contract resolver动态排除属性。您可能需要一些链接路由和参数的全局配置,以便您可以根据当前请求决定何时忽略属性。

    如果它由Microsoft修复,那么所有这些都会更容易,所以它开箱即用!