pm100
pm100

Reputation: 50190

asp.net MVC 3 - reading POST payload in paramterized controller method

I had

[HttpPost]        
public ActionResult Foo()
{
    // read HTTP payload
    var reqMemStream = new MemoryStream(HttpContext.Request.BinaryRead(HttpContext.Request.ContentLength));
 ....
}

The payload is application/json; worked fine; then I changed to

public ActionResult Foo(string thing)
{
....
}

The intention being to post to MyController/Foo?thing=yo Now I cant read the payload(the length is correct but the stream is empty). My guess is that the controller plumbing has eaten the payload looking for form post data that can be mapped to the method parameters. Is there some way that I can stop this behavior (surely MVC should not have eaten a payload whose type is marked as JSON , it should only look at form post data). My work around is to add 'thing' to the json but I dont really like that

Upvotes: 0

Views: 4810

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038880

Try resetting the input stream position before reading:

public ActionResult Foo(string thing)
{
    Request.InputStream.Position = 0;
    var reqMemStream = new MemoryStream(HttpContext.Request.BinaryRead(HttpContext.Request.ContentLength));
    ....
}

Now this being said, if you are sending an application/json payload why on the holy Earth are you bothering to read directly the request stream instead of simply defining and using a view model:

public class MyViewModel
{
    public string Thing { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }
    ...
}

and then:

public ActionResult Foo(MyViewModel model)
{
    // use the model here 
    ....
}

ASP.NET MVC 3 has a built-in JsonValueProviderFactory which allows you to automatically bind JSON requests to models. And if you are using an older version it is trivially easy to add such factory your self as Phil Haack illustrates in his blog post.

Upvotes: 3

Related Questions