Model binding on POSThttp://forums.asp.net/t/1776378.aspx/1?Model+binding+on+POSTSat, 17 Mar 2012 20:44:01 -040017763784862322http://forums.asp.net/p/1776378/4862322.aspx/1?Model+binding+on+POSTModel binding on POST <p>I have this simple controller:</p> <pre class="prettyprint">public class TestController : ApiController { public HttpResponseMessage Get(string id) { return new HttpResponseMessage(HttpStatusCode.OK); } public HttpResponseMessage Post(string id) { var content = Request.Content.ReadAsStringAsync().Result; return new HttpResponseMessage(HttpStatusCode.OK); } }</pre> <p></p> <p>The route is this:</p> <pre class="prettyprint">routes.MapHttpRoute( "test", "{controller}/asdf/{id}"</pre> <p></p> <p>Could you explain on this simple scenario why would this test pass:</p> <pre class="prettyprint">var uri = new Uri(baseUri, "test/asdf/someId")<br />response = client.GetAsync(uri).Result; response.EnsureSuccessStatusCode();</pre> <p></p> <p>And this fail:</p> <pre class="prettyprint">var uri = new Uri(baseUri, "test/asdf/someId")<br />response = client.PostAsync(uri, new StringContent("some content")).Result; response.EnsureSuccessStatusCode();</pre> <p>The secod test fails with InvalidOperationException: 'Headers.ContentType' must be set before 'ObjectContent' can serialize its content. The controllers Post method isn't invoked. The test passes if the 'id' parameter of the Post action is removed.</p> <p>Thanks</p> 2012-03-03T19:20:41-05:004862439http://forums.asp.net/p/1776378/4862439.aspx/1?Re+Model+binding+on+POSTRe: Model binding on POST <p>The reason you are getting the InvalidOperationException on the Post is due to the fact that there is not a &quot;text/plain&quot; media type formatter in the framework. &nbsp;You will need to create a custom&nbsp;<strong>MediaTypeFormatter&nbsp;</strong>that understands this content-type. Also, make sure to add the new formatter to your&nbsp;<strong>HttpConfiguration</strong> formatters collection during application startup.</p> <p>Cheers,</p> <p>Dave</p> 2012-03-04T01:48:18-05:004862465http://forums.asp.net/p/1776378/4862465.aspx/1?Re+Model+binding+on+POSTRe: Model binding on POST <p>I should elaborate on this response. &nbsp;WebAPI is trying to model bind your &quot;someId&quot; parameter, and looks for a plain/text formatter and pukes since there is not one available. If you remove your parameter (a parameterless Post method) then it works fine.</p> 2012-03-04T02:57:19-05:004862632http://forums.asp.net/p/1776378/4862632.aspx/1?Re+Model+binding+on+POSTRe: Model binding on POST <p>Thanks for your replies. They were really helpful.</p> <p>Instead of creating MediaTypeFormatter for 'text/plain' I'm now relying on built in formatter for application/xml by sending an object with content type set to 'application/xml'. Now it works fine but one thing. My {id} URL segment is bound to GET action as expected, but it's null on POST.</p> <p>The controller:</p> <pre class="prettyprint">public class TestController : ApiController { public HttpResponseMessage Get(string id) { return new HttpResponseMessage(HttpStatusCode.OK); } public HttpResponseMessage Post(string id, Content content) { return new HttpResponseMessage(HttpStatusCode.OK); } } public class Content { public string Value { get; set; } }</pre> <p></p> <p>When GET request is sent with this code:</p> <pre class="prettyprint"> var response = client.GetAsync("test/asdf/someId"); </pre> <p>I can see in the debugger the value of 'id' argument in Get action being 'someId'.</p> <p>When POST is sent:</p> <pre class="prettyprint">var request = new HttpRequestMessage(); var content = request.CreateContent(new Content { Value = "some content" }); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/xml"); var response = client.PostAsync("test/asdf/someId", content).Result;</pre> <p>in the debugger in the Post action I see 'content' argument being model bound correctly and 'id' being null.</p> <p>What's the move here to get 'id' bound to Post action as well?</p> <p>Thanks,<br> Vitaly&nbsp;</p> 2012-03-04T07:54:14-05:004882754http://forums.asp.net/p/1776378/4882754.aspx/1?Re+Model+binding+on+POSTRe: Model binding on POST <p>I actually have the exact same problem. With POST and body parameters, I can either get complex working or primitives working, but not both at the same time.</p> <p></p> <p>To get a complex parameter working, I need to change the Read Policy to AsSingleObject - but this breaks the other parameters that were correctly bound by model binding.</p> 2012-03-16T02:31:26-04:004885579http://forums.asp.net/p/1776378/4885579.aspx/1?Re+Model+binding+on+POSTRe: Model binding on POST <p>This was confirmed as a bug which should be fixed in the next version.</p> 2012-03-17T20:44:01-04:00