New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recommended way to read the Request.Body in an ActionFilter #5260

Closed
damienbod opened this Issue Sep 9, 2016 · 12 comments

Comments

Projects
None yet
4 participants
@damienbod

damienbod commented Sep 9, 2016

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

The Body property in the ActionExecutingContext cannot be read.

Thanks Damien

@damienbod damienbod changed the title from Reccommended why to read Request.Body in an ActionFilter to Recommended why to read Request.Body in an ActionFilter Sep 9, 2016

@damienbod damienbod changed the title from Recommended why to read Request.Body in an ActionFilter to Recommended way to read Request.Body in an ActionFilter Sep 9, 2016

@davidfowl

This comment has been minimized.

Show comment
Hide comment
@davidfowl

davidfowl Sep 9, 2016

Member

What are you trying to do with the body?

Member

davidfowl commented Sep 9, 2016

What are you trying to do with the body?

@damienbod

This comment has been minimized.

Show comment
Hide comment
@damienbod

damienbod Sep 9, 2016

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

damienbod commented Sep 9, 2016

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

@damienbod

This comment has been minimized.

Show comment
Hide comment
@damienbod

damienbod Sep 9, 2016

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

damienbod commented Sep 9, 2016

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

@damienbod damienbod changed the title from Recommended way to read Request.Body in an ActionFilter to Recommended way to read the Request.Body in an ActionFilter Sep 9, 2016

@rynowak

This comment has been minimized.

Show comment
Hide comment
@rynowak

rynowak Sep 9, 2016

Member

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

Member

rynowak commented Sep 9, 2016

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

@damienbod

This comment has been minimized.

Show comment
Hide comment
@damienbod

damienbod Sep 9, 2016

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

damienbod commented Sep 9, 2016

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

@rynowak

This comment has been minimized.

Show comment
Hide comment
@rynowak

rynowak Sep 9, 2016

Member

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.

Member

rynowak commented Sep 9, 2016

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.

@damienbod

This comment has been minimized.

Show comment
Hide comment
@damienbod

damienbod Sep 9, 2016

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

Greetings Damien

damienbod commented Sep 9, 2016

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

Greetings Damien

@damienbod damienbod closed this Sep 9, 2016

@damienbod

This comment has been minimized.

Show comment
Hide comment
@nhwilly

This comment has been minimized.

Show comment
Hide comment
@nhwilly

nhwilly May 2, 2017

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 commented May 2, 2017

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.

@rynowak

This comment has been minimized.

Show comment
Hide comment
@rynowak

rynowak May 3, 2017

Member

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

Member

rynowak commented May 3, 2017

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

@nhwilly

This comment has been minimized.

Show comment
Hide comment
@nhwilly

nhwilly May 3, 2017

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

nhwilly commented May 3, 2017

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

@rynowak

This comment has been minimized.

Show comment
Hide comment
@rynowak

rynowak May 3, 2017

Member

🐕 🌑 🌵

Member

rynowak commented May 3, 2017

🐕 🌑 🌵

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment