ASPNetCore - Uploading a file through REST

梦想与她 提交于 2019-11-30 15:29:58

问题


I am using Insomnia for testing an API, but the same happens with Postman.

I want to test a file upload, with the following controller:

public async Task<IActionResult> Post([FromForm]IFormFile File)

If I set the request as a multipart request:

it works.

However, if I set it as a binary file:

I don't know how to get the data. How can it be done?

Also, in the controller method's signature, if I change [FromForm] to [FromBody], I'm not getting data.

Can someone clarify this for me?


回答1:


As you've noticed already, using binary file option in Postman/Insomnia doesn't work the standard way. There are three different ways to upload file via RESTful API, and you have to choose one.

I've included code snippets that read the uploaded file contents to a string and output it -- try sending a text file, and you should get the contents of the file in the 200 response.

Form-data upload

This is the most popular/well-known upload method formatting the data you send as a set of key/value pairs. You normally need to specify Content-Type to multipart/form-data in the request, and then use [FromForm] attribute in MVC to bind values to variables. Also, you can use the built-in IFormFile class to access the file uploaded.

[HttpPost]
public async Task<IActionResult> PostFormData([FromForm] IFormFile file)
{
    using (var sr = new StreamReader(file.OpenReadStream()))
    {
        var content = await sr.ReadToEndAsync();
        return Ok(content);
    }
}

Body upload

You can send body in the format that MVC understands, e.g. JSON, and embed the file inside it. Normally, the file contents would be encoded using Base64 or other encoding to prevent character encoding/decoding issues, especially if you are sending images or binary data. E.g.

{
    "file": "MTIz"
}

And then specify [FromBody] inside your controller, and use class for model deserialization.

[HttpPost]
public IActionResult PostBody([FromBody] UploadModel uploadModel)
{
    var bytes = Convert.FromBase64String(uploadModel.File);
    var decodedString = Encoding.UTF8.GetString(bytes);
    return Ok(decodedString);
}
// ...
public class UploadModel
{
    public string File { get; set; }
}

When using large and non-text files, the JSON request becomes clunky and hard to read though.

Binary file

The key point here is that your file is the whole request. The request doesn't contain any additional info to help MVC to bind values to variables in your code. Therefore, to access the file, you need to read Body in the Request.

[HttpPost]
public async Task<IActionResult> PostBinary()
{
    using (var sr = new StreamReader(Request.Body))
    {
        var body = await sr.ReadToEndAsync();
        return Ok(body);
    }
}


来源:https://stackoverflow.com/questions/50223606/aspnetcore-uploading-a-file-through-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!