Rocky Raccoon Rocky Raccoon - 4 months ago 84
JSON Question

Invalid ModelState, HTTP 400 Bad Request for JSON Array Sent to C# Web API Controller

In a C# Web API, I am trying to accept a

POST
request that contains a JSON array. I want to deserialize the JSON array to a
LIST
or
ILIST
of
RegisterBindingModel
class objects. Then, in the controller actions, I will iterate over the list and perform the desired action.

I am using essentially the stock ASP.NET 5 Web Application template in Visual Studio 2015. I have added a
RegisterList
method on the
Account
controller.

Separately, I have created a Web client in a C# console application. The client sends a POST request that contains a JSON array.

The response I get is always 400 - Bad Request.

Am I supposed to deserialize the JSON array to an ILIST or LIST in the
RegisterList
method signature? I've tried to use
JsonConverter.DeserializeObject
, but IntelliSenese says that
the type name DeserializeObject does not exist in type JsonConverter
.

The API documentation that generates with the Visual Studio template indicates that the client's JSON array is formatted correctly.

The following is the code for the
RegisterList
method:

// POST api/Account/RegisterList
[AllowAnonymous]
[Route("RegisterList")]
public async Task<IHttpActionResult> RegisterList(List<RegisterBindingModel> modelList)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

foreach (RegisterBindingModel model in modelList)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

IdentityResult result = await UserManager.CreateAsync(user, model.Password);

if (!result.Succeeded)
{
return GetErrorResult(result);
}

}
return Ok();
}


The following is the code for the client:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Web_Client_Register_Account;
using Newtonsoft.Json;

namespace Web_Client_Register_Account
{
class Program
{
static void Main(string[] args)
{
RunAsync().Wait();
}

static async Task RunAsync()
{
using (var client = new HttpClient())
{
Console.WriteLine("Hit any key");
Console.ReadLine();
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));





var registrations = new List<Registration> { new Registration { Email = "orc@coast2coast.net", Password = "Secrets1!", ConfirmPassword = "Secrets1!" }, new Registration { Email = "gargoyle@coast2coast.net", Password = "Secrets1!", ConfirmPassword = "Secrets1!" }, new Registration { Email = "elf@coast2coast.net", Password = "Secrets1!", ConfirmPassword = "Secrets1!" }, new Registration { Email = "ranger@coast2coast.net", Password = "Secrets1!", ConfirmPassword = "Secrets1!" } };

//HTTP Post - A JSON List in a Single POST

var registration_manifest = JsonConvert.SerializeObject(registrations);

Console.ReadLine();

HttpResponseMessage response = await client.PostAsJsonAsync("api/Account/RegisterList", registration_manifest);


if (response.IsSuccessStatusCode)
{
Uri registrantUrl = response.Headers.Location;
Console.WriteLine(registrantUrl);
Console.ReadLine();
}
Console.WriteLine(response);
Console.ReadLine();
}
}
}
}

Answer

HttpClient.PostAsJsonAsync already encodes to JSON, so skip the JsonConvert.SerializeObject and just

HttpResponseMessage response = await client.PostAsJsonAsync("api/Account/RegisterList", 
                                                            registrations);
Comments