Mvc: Recommended way to read the Request.Body in an ActionFilter

Created on 9 Sep 2016  路  12Comments  路  Source: aspnet/Mvc

What's the recommended way to read the request body inside an Actionfilter

The Body property in the ActionExecutingContext cannot be read.

Thanks Damien

Most helpful comment

Yes, if you're inside an action filter then context.ActionArguments will contain all of the model objects we created. So if you have:

public IActionResult Edit(int id, [FromBody] Widget widget) { }

Then context.ActionArguments["widget"] will return the Widget object. If you're trying to do this in a generic way, look at context.ActionDescriptor.Parameters - this will contain all of the parameter definitions and metadata.

All 12 comments

What are you trying to do with the body?

I want to validate the model with custom validation which is not possible using the ModelState

Are you trying to prevent developers from implementing validation logic in Filters? After reading the docs, this is not one of the use cases for ActionFilters.

https://docs.asp.net/en/latest/mvc/controllers/filters.html#selecting-a-filter

Greetings Damien

If you must do this inside an action filter then you'll need to buffer the body (new up a memory stream and copy to it, replace the body). ModelBinding runs before action filters so if you have form data or a [FromBody] parameter, we've already read it.

If you can tell us more about what you need to accomplish we can suggest alternatives

Hi @rynowak thanks for your answer. I don't have to validate in the ActionFilter, I just though this would be a good place to put the validation logic before I call the controller method. I use the FromBody in the Controller class to get the data. Can I access this in an ActionFilter?

If not I can always do the validation from the controller class inside the method.

Thanks Damien

Yes, if you're inside an action filter then context.ActionArguments will contain all of the model objects we created. So if you have:

public IActionResult Edit(int id, [FromBody] Widget widget) { }

Then context.ActionArguments["widget"] will return the Widget object. If you're trying to do this in a generic way, look at context.ActionDescriptor.Parameters - this will contain all of the parameter definitions and metadata.

Cool thanks, works perfect. Thanks a million for the tip.

Greetings Damien

Interestingly, if you try to update the model (as I am doing with inbound open id connect claims), the validation has already occurred. You have to force it to validate again.

I tried using a resource filter so I could catch it first, but I couldn't figure out how to determine the object type (which would tell me I needed to insert the data into the model). I can't always assume there is just one model coming in, right? One of the incoming models might not have the properties I need to update.

So I loop through, find the models that need updating, make the updates and then force validation again.

Doesn't sound very efficient, but I can't figure another way to do it. Any suggestions/pointers would be great.

Thanks for the articles and the answers here. Huge help.

@nhwilly It would help if you could open a new issue and explain what you're trying to do from the beginning.

Thanks again for responding. I've done that, here. #6225

馃悤 馃寫 馃尩

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Mr-Smileys picture Mr-Smileys  路  3Comments

michaelbowman1024 picture michaelbowman1024  路  3Comments

workmonitored picture workmonitored  路  3Comments

Lutando picture Lutando  路  4Comments

miroslavsiska picture miroslavsiska  路  4Comments