Search code examples
formsasp.net-coremultipart

Can not send both files and objects within a form


Hello i was wondering how could you send both a POCO and files within a form. My problem is twofold:

  • 1.So far when i acess the Request.Form.Files[0] and copy it in a file i get a 0kb file.
  • If i want to get the MyPoco object from my form when i use the [FromBody] as a parameter to my method i get a 415 not supported type.

Form

<form id="createForm" method="post" enctype="multipart/form-data" action="http://localhost:8300/api/create">

<input type="text" bind="@model.Name"/>//some binding here
<input type="text" bind="@model.Id"/> //some binding...

<input type="file"/>
</form>

Controller

[HttpPost]
        [Route("api/create")]
        public async Task<long> CreateAsync([FromBody] MyPoco poco) { //getting error 415 when using the FromBody 
            try {

                MyPoco poc = poco;
                string path = Path.Combine(
                    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), 
                    "file.csv"); //copy the input file -> getting 0kb file
                FileStream stream = new FileStream(path, FileMode.Create);
                await this.Request.Form.Files[0].CopyToAsync(stream);
                return 3;
            } catch (Exception) {
                return 0;
            }
        }

P.S The syntax of binding is blazor but it is unimportant in this case.


Solution

  • Avoid using [FromBody], it will instruct the ModelBinder to read the whole payload and then serialize it as an instance of MyPoco.

    To acheive your goals, you could declare your action method as below :

    [HttpPost("[action]")]
    public IActionResult Test(MyPoco myPoco,IFormFile myfile){
         // now you get the myfile file and the myPoco 
    }
    

    and then send fields with the complete names :

    <form id="createForm" method="post" enctype="multipart/form-data" action="/api/SampleData/Test">
    
        <input name="MyPoco.Name" type="text" bind="@model.Name" />
        <input name="MyPoco.Id" type="text" bind="@model.Id" />
    
        <input name="myfile" type="file" />
        <button type="submit">submit this form</button>
    </form>
    

    a screenshot of demo :

    enter image description here