I have a simple API I am writing which includes a POST method to insert a new record into a couple of database tables. The data is coming from form data.
One of the items is a collection which includes a few fields.
I am using Swagger to test and when I Post the form data the collection field is blank.
Controller - Post endpoint
[HttpPost("addboardmember")]
public IActionResult PostBoardMember([FromForm] MemberForm memberData)
{
try
{
_memberRepository.PostBoardMember(memberData);
var newMember = _memberRepository.GetMembers().SingleOrDefault(m => m.SSN == memberData.SSN);
var newMemberId = newMember.Member_ID;
var boardArray = memberData.BoardForms;
return Ok();
//return Ok() is temporary, will return 201 with appropriate data
}
catch (Exception ex)
{
return BadRequest("Couldn't Save record??" ex.InnerException.ToString());
}
}
MemberForm class (Abbreviated to highlight the main fields and the field I am struggling with populating: BoardForms
public class MemberForm
{
[Required, NotNull]
public string LastName { get; set; }
[Required, NotNull]
public string FirstName { get; set; }
[Required, NotNull]
public string SSN {get; set;}
public virtual ICollection<BoardForm> BoardForms { get; set; }
}
}
BoardForm class:
public class BoardForm
{
public int Board_ID { get; set; }
public int StartYear { get; set; }
public int EndYear { get; set; }
}
When I test Post API endpoint using Swagger the BoardForms field has a count of zero.

Swagger input.
I will have additional business logic to create a record based on each record in the BoardForm array.
I do not know how I am supposed to access the array being sent in the Form Data which is setup as an ICollection.
Browser Developer Tools payload:

All the elements shown above in the payload screenshot are mapped to their correct elements an I can see the values with the exception of the 'BoardForms' array.
CodePudding user response:
- You're using the wrong attribute and you're formatting your requests incorrectly.
- Use
[FromForm]when you want ASP.NET to bind HTML<form>data posted asapplication/x-www-form-urlencodedormultipart/form-data.- You cannot use
[FromForm]for JSON data.
- You cannot use
- Use
[FromBody]to have ASP.NET use some configuredContent-Type-specific binder to populate an object.- ASP.NET Core supports
application/jsonby default, I don't know what other types are supported in-box (e.g. XML,DataContract, etc) but it is extensible as you can also support gRPC, for example. - You probably should not be using either
<form>content-types (multipart/form-dataandapplication/x-www-form-urlencoded) for any "Web APIs" because those are specific to the idiosyncrasies of HTML's<form>and are unsuitable for describing structured data (such as arbitrary lists of data, or keyed collections), while ASP.NET does support binding<form>/FormDatato objects it is unsuitable for JSON documents.- If you're using
multipart/form-datato allow for binary uploads from client-libraries and headless clients (and not human-operated web-browsers) then I'd advise you to redesign your web-service's to accept binary file uploads as separatePUT/POSTrequests and to not combine DTOs with binary data in the same request.- While ASP.NET Core can bind objects to JSON
(
application/json) andIFormFilefrom othermultipart/form-datarequest parts, this functionality isn't built-in nor turnkey: you'll need to write your own model-binder to handle this scenario - and I don't think it's worth the effort. YMMV.
- While ASP.NET Core can bind objects to JSON
(
- If you're using
- ASP.NET Core supports
- Use
so change this:
[HttpPost("addboardmember")]
public IActionResult PostBoardMember([FromForm] MemberForm memberData)
{
}
to this:
[HttpPost("addboardmember")]
public IActionResult PostBoardMember([FromBody] MemberForm memberData)
{
}
And you might want to ensure your Controller class has [ApiController] applied to it.

