1

I have the following controller action

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

I am trying to limit the allowed properties, and I assumed this would work, however, it doesn't and value receives all the values sent and not just BirthDate - I don't want to use a view model because I want a dynamic object to be sent. FYI, this doesn't work with a normal model object either.

this is the json I am sending in request the body

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

1 Answers1

0

After reading through the source code, when posting a json in the request body, the BodyModelBinder is used. Unfortunately this model binder doesn't seem to apply the PropertyFilters provided by instances of the IPropertyBindingPredicateProvider like the [Bind] attribute.

It just uses the JsonInputFormatter to deserialize the json into the model type:

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;

This seems like a bug to me...

In the meantime, you could try to evaluate some options you have available. As stated in the docs we know the formatter uses Json.Net:

The JsonInputFormatter is the default formatter and it is based off of Json.NET.

So essentially you would need to follow an approach to exclude the properties that works with Json.Net, like using the [JsonIgnore] attribute. (Or just use some DTO object that doesn't contains those properties :))

Of course in your case is harder because you have a dynamic object and not a strongly typed object, which means:

  1. There is no type for you to apply the attributes
  2. Json.net will be unaware of any attributes you set in the controller action.

You could explore updating the JsonSerializerSettings, for example trying to use a contract resolver to dynamically exclude properties. You might possible need some global configuration that links routes and parameters to be ignored, so you can decide when to ignore a property or not based on the current request.

All of this would be much easier if it was fixed by Microsoft so it works out of the box!

Community
  • 1
  • 1
Daniel J.G.
  • 34,266
  • 9
  • 112
  • 112