0

For reasons outlined here I need to review a set values from they querystring or formdata before each request (so I can perform some authentication). The keys are the same each time and should be present in each request, however they will be located in the querystring for GET requests, and in the formdata for POST and others

As this is for authentication purposes, this needs to run before the request; At the moment I am using a MessageHandler.

I can work out whether I should be reading the querystring or formdata based on the method, and when it's a GET I can read the querystring OK using Request.GetQueryNameValuePairs(); however the problem is reading the formdata when it's a POST.

I can get the formdata using Request.Content.ReadAsFormDataAsync(), however formdata can only be read once, and when I read it here it is no longer available for the request (i.e. my controller actions get null models)

What is the most appropriate way to consistently and non-intrusively read querystring and/or formdata from a request before it gets to the request logic?

3 Answers 3

1

Regarding your question of which place would be better, in this case i believe the AuthorizationFilters to be better than a message handler, but either way i see that the problem is related to reading the body multiple times.

After doing "Request.Content.ReadAsFormDataAsync()" in your message handler, Can you try doing the following?

Stream requestBufferedStream = Request.Content.ReadAsStreamAsync().Result;
requestBufferedStream.Position = 0; //resetting to 0 as ReadAsFormDataAsync might have read the entire stream and position would be at the end of the stream causing no bytes to be read during parameter binding and you are seeing null values.

note: The ability of a request's content to be read single time only or multiple times depends on the host's buffer policy. By default, the host's buffer policy is set as always Buffered. In this case, you will be able to reset the position back to 0. However, if you explicitly make the policy to be Streamed, then you cannot reset back to 0.

Sign up to request clarification or add additional context in comments.

2 Comments

adding that works:- ` result = request.Content.ReadAsFormDataAsync().Result; Stream requestStream = request.Content.ReadAsStreamAsync().Result; requestStream.Position = 0; ` Your comment on the buffer policy... does that mean from an application point of view it won't work if the server on which the code is running has that policy set to streamed?
yeah..that's right...you can try it yourself by replacing with Streamed policy like mentioned in this blog post: blogs.msdn.com/b/kiranchalla/archive/2012/09/04/…
0

What about using ActionFilterAtrributes?

Comments

0

this code worked well for me

public HttpResponseMessage AddEditCheck(Check check)
{
    var request= ((System.Web.HttpContextWrapper)Request.Properties.ToList<KeyValuePair<string, object>>().First().Value).Request;

    var i = request.Form["txtCheckDate"];
    return Request.CreateResponse(HttpStatusCode.Ok);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.