如何扩展 .NET Core IFormFileCollection

How to extend .NET Core IFormFileCollection

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

这是我的代码:

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){...}

然后在 body 中你可以将数据转换为你的 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,如何在表单中将标题与文件一起传递? 这是一个创建模型的演示,包括标题和 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>

结果: