【问题标题】:ASP.NET Core Web API submit form has file and text fields errorASP.NET Core Web API 提交表单包含文件和文本字段错误
【发布时间】:2020-09-11 10:07:31
【问题描述】:

我正在使用 .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 有文件和文本字段成功?

【问题讨论】:

标签: c# asp.net-core .net-core postman asp.net-core-webapi


【解决方案1】:

你可以设置 [DataType(DataType.Upload)] public IFormFile file{ get; set; }

在你的模型中

【讨论】:

    【解决方案2】:

    正如@Purushothaman 建议的那样,添加[FromForm] 是一个有效且简单的解决方案,只要您知道自己在做什么。如果您的规范说您希望端点接受multipart/form-data,否则我会选择使用application/json 的端点。

    请记住,大多数 API 在 application/json 而不是 form data 上运行。这可能会在使用 form-data 时导致一些集成问题。

    为什么带有有效 Contant Type 标头的 Postman 请求不起作用?

    设置application/json 并不重要,因为它正在被覆盖。根据documentation form-datadocumentation auto-generated-headers。因此,您发送的 Content-type 标头是 Content Type multipart/form-data 而不是 application/json,这会导致 415 响应。

    如何使用 Postman 发出 POST API 请求

    如果你不想使用 [FormData] 并重新编译服务器代码,在 Postman 中更改设置并不难。

    首先转到 POST 请求中的正文,找到 raw 选项,然后选择右侧旁边的 JSON (application/json) 下拉菜单。以 json 格式粘贴您的数据。

    【讨论】:

    • 谢谢,我会尝试然后反馈。你能让你的答案更明白吗
    猜你喜欢
    • 1970-01-01
    • 2017-02-24
    • 2013-03-29
    • 2017-03-18
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多