27

In ASP.NET MVC , one can access the form post data:

var thisData = Request.Form["this.data"];

Is it possible to achieve the same functionality in a Web API ApiController?

Magnus Johansson
  • 28,010
  • 19
  • 106
  • 164

5 Answers5

36

ASP.NET Web API has become significantly more robust in dealing with different HTTP scenarios - especially streaming. As such only media type formatters normally touch the content and have to make a coherence of the content.

In ASP.NET MVC, application/x-www-form-urlencoded content type is a first class citizen (and treated especially since this is the content type of 95% of the POST requests) and we have the FormsCollection to provide dictionary access in access, whenever it is defined as an input parameter.

In ASP.NET Web API, application/x-www-form-urlencoded is yet another content type, and supposed to be read by its MediaTypeFormatter. As such ASP.NET Web API cannot make any assumption about the Forms.

The normal approach in ASP.NET Web API is to represent the form as a model so the media type formatter deserializes it. Alternative is to define the actions's parameter as NameValueCollection:

public void Post(NameValueCollection formData)
{
   var value = formData["key"];
}
Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • 2
    Suppose you had some values that were known, and some that are dynamic. Is there a way to specify a model type for the known ones, AND get the rest in the collection. Something like: `public void Post(PostData model, NameValueCollection formData)`? – Joshua Frank Mar 14 '14 at 19:50
  • 7
    Using NameValueCollection did not work for me, but it worked with FormDataCollection – Pyfhon Nov 30 '16 at 09:36
  • 3
    NameValueCollection did not work for me too. I used FormDataCollection as @Pyfhon. – xabush Feb 19 '17 at 16:36
19

Well, it is not possible because HttpRequestMessage doesn't provide that kind of collection out of the box.

However, if your application is hosted under ASP.NET, you can get to the current HttpContext object and get the form values from there:

public class CarsController : ApiController {

    public string[] Get() {

        var httpContext = (HttpContextWrapper)Request.Properties["MS_HttpContext"];
        var foo = httpContext.Request.Form["Foo"];

        return new string[] { 
            "Car 1",
            "Car 2",
            "Car 3"
        };
    }
}

But I am not sure if this is the best way of doing this kind of stuff.

tugberk
  • 57,477
  • 67
  • 243
  • 335
5

As an alternative to Aliostad's method, one can do:

public void Post(HttpRequestMessage request)
{
    NameValueCollection formData = await request.Content.ReadAsFormDataAsync();
}
Philip
  • 3,135
  • 2
  • 29
  • 43
1

If you just have an HttpRequestMessage, you have a couple of options:

By referencing System.Net.Http.Formatting, you can use the ReadAsFormDataAsync() extension method.

var formData = await message.Content.ReadAsFormDataAsync();

If you don't want to include that library, you can do the same thing manually by using the HttpUtility helper class in System.Web.

public async Task<NameValueCollection> ParseFormDataAsync(HttpRequestMessage message)
{
    string formString = await message.Content.ReadAsStringAsync();
    var formData = HttpUtility.ParseQueryString(formString);
    return formData;
}
Nick
  • 3,722
  • 2
  • 26
  • 17
-1

Try this:

HttpContext.Current.Request.Form["key"];
Kevin
  • 1,200
  • 1
  • 11
  • 19