c# - 如何使用 .NET Core API 将图像文件上传到数据库?
问题描述
我正在创建一个用户可以发布的应用程序,比如论坛。我正在尝试将图像和文本加载到数据库中,为此,我有两个表,它们都通过 id 相关联。我想出了如何加载文本内容,但我真的不知道如何对图像内容做同样的事情。我正在使用带有相应控制器的 MVC 视图来使用 API。
我正在使用的模型:
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; }
}
创建帖子的 API 控制器:
[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();
}
使用 API 的 MVC 控制器:
[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
}
MVC控制器的视图:
@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>
因此,我已阅读有关上传图像或文件的信息,它表明enctype = "multipart / form-data"
在数据库中上传图像或不同类型的文件时,该属性应出现在视图中,由于该属性,会发生两件事:第一件事是当我离开该属性时在视图中,MVC 控制器不使用 API 控制器,但模型从文件或图像中接收信息,例如名称、文件类型等。第二个是当我从视图中删除属性时,在这种情况下MVC 控制器使用 API 控制器,但模型不包含有关文件或图像的任何内容。在这两种情况下,模型都会接收到文本内容,但由于缺少有关图像的信息,它也不会被数据库保存。
我不太确定enctype = "multipart / form-data"
属性是否是主要原因,但正如我之前所说,在图像上传之前,文本内容运行良好并且enctype = "multipart / form-data"
不存在。
我在 img 上传上停留了一段时间,真的我不知道该怎么做,感谢任何帮助。
解决方案
public IFormFile ContentFile { get; set; }
首先请注意,该PostAsJsonAsync
方法会将模型数据序列化为 JSON 然后发送到请求正文中,序列化 a 没有意义FormFile
,会导致错误。
要实现从 MVC 控制器操作中使用 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 操作
public async Task<IActionResult> createPost([FromForm]ForumThemeModel model)
{
//...
推荐阅读
- php - 如何使用 GitLab API 获取合并分支的列表?
- javascript - 切换选项卡时未触发 setOnNavigatorEvent 回调
- memory - Discord 如何从游戏中读取内存?
- java - 为什么编译器说这个java代码“可能有损从int到字节的转换”?
- python - 这 2 段代码有何不同?
- django - 安装 pipenv 导致 pip3 无法使用
- c# - C# 如何用 . 替换 " 使用 String.replace()
- java - 从大小为 N 的数组生成一组 M 个元素的概率
- python - 找不到 CSRF 令牌
- python - 在 python 中使用非整数类型的枚举是一种不好的做法吗?