[英]Receive file and other form data together in ASP.NET Core Web API (boundary based request parsing)
[英]ASP.NET Core Web API submit form has file and text fields error
我正在使用 .NET 5.0.100-preview.8.20417.9、ASP.NET Core 5 Web API、Entity Framework Core 5、SQL Server 2019、Postman v7.32.0。
模型
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace shadow.DTO
{
public partial class TrustedPersonUserDTO
{
public string Fullname { get; set; }
public string AliasName { get; set; }
public string Email { get; set; }
public string PhoneNumber1 { get; set; }
public string PhoneNumber2 { get; set; }
public string PhoneNumber3 { get; set; }
public int? RelationshipId { get; set; }
public string About { get; set; }
public int? AvatarId { get; set; }
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
// Id của user.
public string UserId { get; set; }
}
public partial class TrustedPersonUserDTO2
{
public string Fullname { get; set; }
public string AliasName { get; set; }
public string Email { get; set; }
public string PhoneNumber1 { get; set; }
public string PhoneNumber2 { get; set; }
public string PhoneNumber3 { get; set; }
public int? RelationshipId { get; set; }
public string About { get; set; }
public int? AvatarId { get; set; }
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
// Id của user.
public string UserId { get; set; }
public IFormFile file { get; set; }
}
}
和控制器
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using shadow.Data;
using shadow.DTO;
using shadow.Models;
using shadow.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace shadow.Controllers
{
[Route("[controller]")]
[ApiController]
public class UserTrustedPersonController : ControllerBase
{
private IUserService _userService;
private IMailService _mailService;
private IConfiguration _configuration;
private ApplicationDbContext _db;
public static IWebHostEnvironment _environment;
public UserTrustedPersonController(IUserService userService, IMailService mailService, IConfiguration configuration, ApplicationDbContext db, IWebHostEnvironment environment)
{
_userService = userService;
_mailService = mailService;
_configuration = configuration;
_db = db;
_environment = environment;
}
/// <summary>
/// Thêm mới người ủy thác kèm Relationship.
/// </summary>
/// <param name="trustedPersonUserDTO"></param>
/// <returns></returns>
[HttpPost]
[Authorize]
public async Task<ActionResult<TrustedPersonUserDTO>> AddUserTrustedPersons(TrustedPersonUserDTO trustedPersonUserDTO)
{
var item = new TrustedPerson
{
Fullname = trustedPersonUserDTO.Fullname,
About = trustedPersonUserDTO.About,
AliasName = trustedPersonUserDTO.AliasName,
AvatarId = trustedPersonUserDTO.AvatarId,
Created = DateTime.Now,
Email = trustedPersonUserDTO.Email,
PhoneNumber1 = trustedPersonUserDTO.PhoneNumber1,
PhoneNumber2 = trustedPersonUserDTO.PhoneNumber2,
PhoneNumber3 = trustedPersonUserDTO.PhoneNumber3,
RelationshipId = trustedPersonUserDTO.RelationshipId
};
_db.TrustedPeople.Add(item);
await _db.SaveChangesAsync();
UserTrustedPerson userTrustedPerson = new UserTrustedPerson();
userTrustedPerson.UserId = trustedPersonUserDTO.UserId;
userTrustedPerson.TrustedPersonId = item.Id;
_db.UserTrustedPeople.Add(userTrustedPerson);
await _db.SaveChangesAsync();
return Ok(userTrustedPerson);
}
/// <summary>
/// Thêm mới người ủy thác kèm Relationship.
/// </summary>
/// <param name="trustedPersonUserDTO"></param>
/// <returns></returns>
[HttpPost]
[Route("add")]
[Authorize]
public async Task<ActionResult<TrustedPersonUserDTO>> AddUserTrustedPersons2(TrustedPersonUserDTO2 trustedPersonUserDTO)
{
var item = new TrustedPerson
{
Fullname = trustedPersonUserDTO.Fullname,
About = trustedPersonUserDTO.About,
AliasName = trustedPersonUserDTO.AliasName,
AvatarId = trustedPersonUserDTO.AvatarId,
Created = DateTime.Now,
Email = trustedPersonUserDTO.Email,
PhoneNumber1 = trustedPersonUserDTO.PhoneNumber1,
PhoneNumber2 = trustedPersonUserDTO.PhoneNumber2,
PhoneNumber3 = trustedPersonUserDTO.PhoneNumber3,
RelationshipId = trustedPersonUserDTO.RelationshipId
};
_db.TrustedPeople.Add(item);
await _db.SaveChangesAsync();
await WriteFile(trustedPersonUserDTO.file);
UserTrustedPerson userTrustedPerson = new UserTrustedPerson();
userTrustedPerson.UserId = trustedPersonUserDTO.UserId;
userTrustedPerson.TrustedPersonId = item.Id;
_db.UserTrustedPeople.Add(userTrustedPerson);
await _db.SaveChangesAsync();
return Ok(userTrustedPerson);
}
public class FileUploadAPI
{
public IFormFile files { get; set; }
}
[HttpPost]
[Route("upload2")]
[Obsolete]
public async Task<string> Post(FileUploadAPI objFile)
{
try
{
if (objFile.files.Length > 0)
{
if (!Directory.Exists(_environment.WebRootPath + "\\Upload\\"))
{
Directory.CreateDirectory(_environment.WebRootPath + "\\Upload\\");
}
using (FileStream fileStream = System.IO.File.Create(_environment.WebRootPath + "\\Upload\\" + objFile.files.FileName))
{
objFile.files.CopyTo(fileStream);
fileStream.Flush();
return "\\Upload\\" + objFile.files.FileName;
}
}
else
{
return "Failed";
}
}
catch (Exception ex)
{
return ex.Message.ToString();
}
}
// Upload file ảnh.
[HttpPost("upload", Name = "upload")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(string), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> UploadFile(IFormFile file, CancellationToken cancellationToken)
{
if (CheckIfExcelFile(file))
{
await WriteFile(file);
}
else
{
return BadRequest(new { message = "Invalid file extension" });
}
return Ok();
}
/// <summary>
/// Method to check if file is excel file
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private bool CheckIfExcelFile(IFormFile file)
{
var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
return (extension == ".png" || extension == ".jpg" || extension == ".bmp" || extension == ".gif" || extension == ".tif"); // Change the extension based on your need
}
private async Task<bool> WriteFile(IFormFile file)
{
bool isSaveSuccess = false;
string fileName;
try
{
var extension = "." + file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
fileName = DateTime.Now.Ticks + extension; //Create a new Name for the file due to security reasons.
var pathBuilt = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files");
if (!Directory.Exists(pathBuilt))
{
Directory.CreateDirectory(pathBuilt);
}
var path = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files", fileName);
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
isSaveSuccess = true;
}
catch (Exception e)
{
//log error
}
return isSaveSuccess;
}
}
}
我打电话给POST
http://localhost:5002/UserTrustedPerson/add
错误
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
"title": "Unsupported Media Type",
"status": 415,
"traceId": "00-a1fc92edfaf6884d8d74e30c21090e87-7acaa91089108e49-00"
}
如何调用 POST RESTful API 有文件和文本字段成功?
你可以设置[DataType(DataType.Upload)] public IFormFile file{ get; set; }
[DataType(DataType.Upload)] public IFormFile file{ get; set; }
在你模型
正如@Purushothaman 建议添加[FromForm]
是一个有效且简单的解决方案,只要您知道自己在做什么。 如果您的规范说您希望端点接受multipart/form-data
否则我会选择使用application/json
端点。
请记住,大多数 API 对application/json
进行操作,而不是对form data
。 在使用form-data
时,这可能会导致一些集成问题。
设置application/json
并不重要,因为它正在被覆盖。 根据文档 form-data和文档 auto-generated-headers 。 因此,您发送的 Content-type 标头是 Content Type multipart/form-data
而不是application/json
,这会导致415
响应。
如果不想使用【FormData】重新编译服务端代码,在Postman中更改设置也不难。
首先转到 POST 请求中的正文,找到原始选项并选择右侧旁边的 JSON (application/json) 下拉列表。 以 json 格式粘贴您的数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.