简体   繁体   English

如何使用 .NET Core API 将图像文件上传到数据库?

[英]How to upload image files to database with .NET Core API?

I am creating an application where a user can post, something like a forum.我正在创建一个用户可以发布的应用程序,比如论坛。 I am trying to load an image and text into the database, for that, I have two tables and they are both related through an id.我正在尝试将图像和文本加载到数据库中,为此,我有两个表,它们都通过 id 相关联。 I figured out how to load text content, but I really don't know how to do the same with image content.我想出了如何加载文本内容,但我真的不知道如何对图像内容做同样的事情。 I'm using an MVC view with it respective controller to consume the API.我正在使用 MVC 视图和它各自的 controller 来使用 API。

The model I'm using:我正在使用的 model:

public class ForumThemeModel
{
    public ForumThemeModel()
    {
        Themes = new HashSet<Theme>();
    }

    //forum table
    [Key]
    public int IdForum { get; set; }
    public string PostTittle { get; set; }

    //theme table
    public int? Idtheme { get; set; }
    public string TextContent { get; set; }
    public int? IdForum { get; set; }
    public IFormFile ContentFile { get; set; } //where the image will be stored
    public string FileNameA { get; set; }
    public string FileType { get; set; }
}

The API controller where the post creation is made:进行帖子创建的 API controller :

    [HttpPost]
    [Consumes("multipart/form-data")]
    [Route("createPost")]
    public async Task<IActionResult> createPost([FromBody]ForumThemeModel model)
    {
        Forum forum = new Forum();

        Theme theme = new Theme();

        var fileName = Path.GetFileName(model.FileNameA);
        var fileExt = Path.GetExtension(fileName);
        var newFileName = String.Concat(Convert.ToString(Guid.NewGuid()), fileExt);

        using(var target = new MemoryStream())
        {
            await model.ContentFile.CopyToAsync(target);
            theme.ContentFile = target.ToArray();
        }

        forum.PostTittle = model.PostTittle;
        theme.FileNameA = newFileName;
        theme.FileType = fileExt;

        var postTittle = new SqlParameter("@postTittle", forum.PostTittle);
        var textContent = new SqlParameter("@textContent", theme.TextContent);
        var content_file = new SqlParameter("@content_file", theme.ContentFile);
        var file_name_a = new SqlParameter("@file_name_a", theme.FileNameA);
        var FileType = new SqlParameter("@FileType", theme.FileType);

        //saves everything to database

        return Ok();
    }

The MVC controller where the API is used:使用了 API 的 MVC controller:

    [HttpPost]
    public IActionResult createPost(ForumThemeModel model)
    {
        HttpClient hc = new HttpClient();
        hc.BaseAddress = new Uri("https://localhost:44325/api/Users");

        var userPost = hc.PostAsJsonAsync<ForumThemeModel>("Users/createPost", model);

        userPost.Wait();
        
        //do something when the resquest result is successful
    }

The view of the MVC controller: MVC controller 的视图:

@model Huerbog.Models.Request.ForumThemeModel

@{
     ViewData["Title"] = "CreatePost";
 }
 <hr />
 <div class="row">
    <div class="col-12 col-md-9">
        <form enctype="multipart/form-data" asp-action="createPost">
           <div asp-validation-summary="ModelOnly" class="text-danger"></div>

           <div class="form-group h4">
              <label asp-for="PostTittle" class="control-label">Tittle</label>
              <input asp-for="PostTittle" class="form-control" />
              <span asp-validation-for="PostTittle" class="text-danger"></span>
           </div>
           <div class="form-group h4">
              <label asp-for="Content" class="control-label">Content of the post</label>
              <textarea rows="5" asp-for="Content" class="form-control"></textarea>
              <span asp-validation-for="Content" class="text-danger"></span>
           </div>
           <div class="form-group h4">
              <label asp-for="ContentFile" class="control-label">Imagen:</label><br />
              <input class="form-control-file" multiple asp-for="ContentFile" type="file" />
           </div>
           <div class="form-group h4">
              <input type="submit" value="Create post" class="btn btn-primary" />
           </div>
         </form>
    </div>
 </div>

So I have read about uploading images or files and it indicates that the attribute enctype = "multipart / form-data" should be present in the view when uploading images or different types of files in a database, due to that attribute two things happen: the first is that when I leave the attribute in the view the MVC controller does not use the API controller, but the model receives the information from the file or image such as the name, the file type, etc. The second is when I remove the attribute from the view, in this case the MVC controller makes use of the API controller, but the model does not contain anything regarding the file or the image.因此,我已阅读有关上传图像或文件的信息,它表明在数据库中上传图像或不同类型的文件时,属性enctype = "multipart / form-data"应该存在于视图中,因为该属性会发生两件事: the first is that when I leave the attribute in the view the MVC controller does not use the API controller, but the model receives the information from the file or image such as the name, the file type, etc. The second is when I remove the attribute from the view, in this case the MVC controller makes use of the API controller, but the model does not contain anything regarding the file or the image. In both cases the text content is received by the model, but it is also not saved by the database due to the lack of information regarding the image.在这两种情况下,文本内容都由 model 接收,但由于缺少有关图像的信息,它也没有被数据库保存。

I'm not very sure if the enctype = "multipart / form-data" atribute is the main reason, but as I said before, the text content, before the image upload, was working well and the enctype = "multipart / form-data" was not present.我不太确定enctype = "multipart / form-data"属性是否是主要原因,但正如我之前所说,在图片上传之前,文本内容运行良好,并且enctype = "multipart / form-data"不存在。

I've stuck on the img upload for a while and really I don't know how to do it, any help is appreciated.我在 img 上传上停留了一段时间,真的我不知道该怎么做,感谢任何帮助。

public IFormFile ContentFile { get; set; }

Firstly, please note that PostAsJsonAsync method would serialize the model data as JSON then send in the request body, which does not make sense to serialize a FormFile , it would cause an error.首先,请注意PostAsJsonAsync方法会将 model 数据序列化为 JSON 然后发送到请求正文中,这对序列化FormFile没有意义,会导致错误。

To achieve the requirement of consuming an API from MVC controller action to upload file(s) with other data, you can refer to the following example code.为了实现使用 MVC controller 动作中的 API 来上传文件和其他数据的需求,您可以参考以下示例代码。

[HttpPost]
public async Task<IActionResult> CreatePost(ForumThemeModel model)
{
    var formContent = new MultipartFormDataContent();

    formContent.Add(new StringContent(model.PostTittle), "PostTittle");

    //...
    //for other properties, such as FileNameA, FileType etc
    //...

    formContent.Add(new StreamContent(model.ContentFile.OpenReadStream()), "ContentFile", Path.GetFileName(model.ContentFile.FileName));


    HttpClient hc = new HttpClient();
    hc.BaseAddress = new Uri("https://localhost:44325/api/Users/");

    var userPost = await hc.PostAsync("createPost", formContent);

    //...

API action API 动作

public async Task<IActionResult> createPost([FromForm]ForumThemeModel model) 
{
    //...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM