Upload with ASP.NET Core json vs formdata

3

I'm using asp.net core webapi , initially my actions were using the [FromBody] attribute in the parameters, so I redeemed the json value sent by the front end . Now I'm implementing a screen that has upload , and I had to use formdata to send the file, and at that point I inserted my object (which I previously sent as json) into my formdata . So, I needed to change my backend to accept the formdata, just remove [FromBody].

I wanted to be able to use my action, either by passing formdata or passing a json, is it possible? As?

    
asked by anonymous 01.09.2017 / 13:20

1 answer

1

I can illustrate with Minimal Example , because it does not have as many specific details in the question and the action question is responsible for both types to receive the information and the file unfortunately does not give, what can be done is as an example below for a submission with jQuery + FormData and other Action receiving json with [FromBody] .

I have a class Elemento :

public class Elemento
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

and a form on the page in addition to the two fields, will be passed via an image of a input type file with FormData :

  • <form>

    <form name="form1" id="form1">
        <input type="text" name="Id" value="1" />
        <input type="text" name="Nome" value="@Guid.NewGuid()" />
        <input type="file" name="arquivo" id="arquivo" />
        <button type="button" onclick="send()">Enviar</button>
    </form>
    
  • ajax

    function send() {
        var items = ($("#form1").serializeArray());
        var form = new FormData();
        for (i = 0; i < items.length; i++)
        {
            form.append(items[i].name.toLocaleLowerCase(), items[i].value);
        }
        form.append('arquivo', $('#arquivo')[0].files[0]);            
        $.ajax({
            type: "POST",
            url: "/api/Elementos",
            contentType: false,
            processData: false,
            data: form,
            success: function (message) {
                // code
            },
            error: function () {
                //code
            }
        });
    }
    
  • controller/action

    [HttpPost]
    public IActionResult Post(Elemento elemento,IFormFile arquivo)
    {
        // aqui também recupera
        var resultForm = Request?.Form;
    
        // aqui de forma automática
        var ele = elemento;
        var arq = arquivo; // a foto enviado            
        return Ok(new { e = elemento });
    }
    

Full page code:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebApplication2</title>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script></head><body><h2>Index</h2><formname="form1" id="form1">
        <input type="text" name="Id" value="1" />
        <input type="text" name="Nome" value="@Guid.NewGuid()" />
        <input type="file" name="arquivo" id="arquivo" />
        <button type="button" onclick="send()">Enviar</button>
    </form>
    <script>
        function send() {
            var items = ($("#form1").serializeArray());
            var form = new FormData();
            for (i = 0; i < items.length; i++)
            {
                form.append(items[i].name.toLocaleLowerCase(), items[i].value);
                console.log(items[i].name.toLocaleLowerCase() + ':' + items[i].value);
            }
            form.append('arquivo', $('#arquivo')[0].files[0]);            
            $.ajax({
                type: "POST",
                url: "/api/Elementos",
                contentType: false,
                processData: false,
                data: form,
                success: function (message) {
                    alert(message);
                },
                error: function () {
                    alert("There was error uploading files!");
                }
            });
        }
    </script>
</body>
</html>

Debug performed for testing:

  

  

01.09.2017 / 15:45