如何扩展 .NET Core IFormFileCollection

问题描述

我正在开发一个 ASP.NET Core 5 Web API 项目,我想保存一个包含多个文件的帖子。每个文件都应包含名称标题

这是我的代码

public class PostDTO
{
    public Guid? CategoryId { get; set; }
    public Guid UserID { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string Tags { get; set; }

    public IFormFileCollection FileList { get; set; }
}

[HttpPost]
public async Task<IActionResult> Post([FromForm] PostDTO postDTO)
{
    if (postDTO == null)
        throw new ArgumentNullException(nameof(postDTO));

    List<PostAttachmentFileDataStructure> FileList = new();

    if (postDTO.FileList != null)
        foreach (var Attachment in postDTO.FileList)
            FileList.Add(PostAttachmentFileDataStructure.Create(Guid.NewGuid(),"FileTitle",Attachment));

        try
        {
            await commandBus.Send(PostCommand.Create(Guid.NewGuid(),postDTO.PostTitle,postDTO.PostContent,postDTO.CategoryId,postDTO.UserID,postDTO.Tags.normalizedinput(),FileList));
        }
        catch (Exception)
        {
            return StatusCode(500);
        }

        return Ok();
}

如您所知,IFormFileIFormFileCollection 没有任何类似 Title属性。所以我想扩展 IFormFileCollection添加一个名为 Title属性

有没有办法做到这一点?

谢谢。

解决方法

在后端:

代替

public class PostDTO
{
    public Guid? CategoryId { get; set; }
    public Guid UserID { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string Tags { get; set; }

    public IFormFileCollection FileList { get; set; }
}

public async Task<IActionResult> Post([FromForm] PostDTO postDTO){...}

你应该使用:

public class PostDTO
{
    public Guid? CategoryId { get; set; }
    public Guid UserID { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public string Tags { get; set; }
    public List<FileInfo> FileInfos { get; set; }
}

 public class FileInfo
    {
        public string title{ get; set; }
        public string filename { get; set; }
    }

public async Task<IActionResult> Post( IFormCollection dto){...}

然后在正文中您可以将数据转换为您的 dto

PostDTO postDTO = JsonConvert.DeserializeObject<PostDTO>(dto["data"]);

用于访问您可以使用的上传文件

dto.Files

在前端:

    const data = {
            categoryId: "1",postTitle: "1",postContent: "1",userId: "1",tags: "1",fileInfos: [
              { title: "1",fileName: "1" },{ title: "2",fileName: "2" },],};
          const formData = new FormData();
          formData.append("data",JSON.stringify(data));
          formData.append("files","file that has been uploaded");

      axios
        .post("your api URL",formData)
,

如果您向 IFormFile 添加标题,您如何在表单中将标题与文件一起传递? 下面是一个演示,创建一个包含 Title 和 IFormFile 的模型,并使用 ajax 传递示例数据:

型号:

public class FileModel
    {
        public string Title { get; set; }
        public IFormFile File { get; set; }
    }
public class PostDTO
    {
        public Guid? CategoryId { get; set; }
        public Guid UserID { get; set; }
        public string PostTitle { get; set; }
        public string PostContent { get; set; }
        public string Tags { get; set; }

        public List<FileModel> FileList { get; set; }
    }

查看:

<form>
    <input type="file" id="files" multiple/>
    <input type="button" value="submit" onclick="PostFiles()" />
</form>
<script>
function PostFiles() {
            var formData = new FormData();
            var files = $("#files").get(0).files;
            for (var i = 0; i < files.length; i++)
            {
                formData.append("FileList[" + i + "].Title","title"+i);
                formData.append("FileList[" + i + "].File",files[i]);

            }
            $.ajax({
                type: "POST",url: "Post",data: formData,processData: false,contentType: false,success: function (data) {
                }

            });
        }
</script>

结果: enter image description here