如何使用 .NET Core API 将图像文件上传到数据库?
How to upload image files to database with .NET Core API?
我正在创建一个用户可以 post 的应用程序,类似于论坛。我正在尝试将图像和文本加载到数据库中,为此,我有两个表,它们都通过一个 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; }
}
创建 post 的 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 然后在请求正文中发送,这对序列化 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)
{
//...
我正在创建一个用户可以 post 的应用程序,类似于论坛。我正在尝试将图像和文本加载到数据库中,为此,我有两个表,它们都通过一个 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; }
}
创建 post 的 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 然后在请求正文中发送,这对序列化 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)
{
//...