Skip to content

Instantly share code, notes, and snippets.

@pedroreys
Created May 22, 2012 17:06
Show Gist options
  • Save pedroreys/2770310 to your computer and use it in GitHub Desktop.
Save pedroreys/2770310 to your computer and use it in GitHub Desktop.
Self Host Web API Model Binding Issue

I have a self hosted web api that has a controller with a Post action that takes a single string argument.

Model binding is failing to set the value of the argument and it's being passed null, even though the value is correct in the HttpContent object.

Below are a Controller and a test that reproduces the issue.

This bug was filled on codeplex: http://aspnetwebstack.codeplex.com/workitem/171

UPDATE

It was not a bug, but a behavior by design. For simple types, as string, WebAPI defaults Parameter Binding to QueryString parameters. To have it inspect the Request Body, either the argument needs to be decorated with a [FromBody] attribute or wrapped in a complex type.

See Mike Stall's post for more details on WebApi parameter binding

namespace System.Web.Http.ModelBinding
{
public class ModelBindingIssueController : ApiController
{
public string Post(string StringArgument)
{
return StringArgument;
}
}
}
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http.SelfHost;
using Xunit;
namespace System.Web.Http.ModelBinding
{
public class ModelBindingIssueTest
{
[Fact]
public void Body_Binds_String_Argument()
{
var httpClient = new HttpClient();
var baseAddress = "http://localhost/";
var configuration = new HttpSelfHostConfiguration(baseAddress);
configuration.Routes.MapHttpRoute("Default", "{controller}");
var server = new HttpSelfHostServer(configuration);
server.OpenAsync().Wait();
string formUrlEncodedString = "StringArgument=Token1";
StringContent stringContent = new StringContent(formUrlEncodedString, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpRequestMessage request = new HttpRequestMessage()
{
RequestUri = new Uri(baseAddress + "ModelBindingIssue"),
Method = HttpMethod.Post,
Content = stringContent,
};
// Act
HttpResponseMessage response = httpClient.SendAsync(request).Result;
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("Token1", response.Content.ReadAsStringAsync().Result);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment