Home > Enterprise >  ASP .NET Core (Net 6) POST Read Array from Form Data
ASP .NET Core (Net 6) POST Read Array from Form Data

Time:01-18

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. Board Forms Count Shows 0

Swagger input.

enter image description here

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: Browser 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 as application/x-www-form-urlencoded or multipart/form-data.
      • You cannot use [FromForm] for JSON data.
    • Use [FromBody] to have ASP.NET use some configured Content-Type-specific binder to populate an object.
      • ASP.NET Core supports application/json by 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-data and application/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> / FormData to objects it is unsuitable for JSON documents.
        • If you're using multipart/form-data to 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 separate PUT/POST requests and to not combine DTOs with binary data in the same request.
          • While ASP.NET Core can bind objects to JSON (application/json) and IFormFile from other multipart/form-data request 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.

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.

  •  Tags:  
  • Related