如何扩展和添加到 .NET Core 中的 IFormFile 接口。提交ajax请求时需要向序列化数组追加数据

How can I extend and add to the IFormFile Interface in .NET Core. Need to append data to the serialised array when submitting an ajax request

我需要使用 .net core 上传文件。

我正在使用多部分表单并且 AJAX。

但是我有一个独特的要求。我需要能够将数据添加到序列化数组,然后通过 ajax POST 请求和模型绑定将其绑定到控制器。

我需要添加一个 ID,我将其传递给控制器​​。根据 id,我决定将上传的文件详细信息保存到 table 中的哪一行。

我要发帖的控制器:

 [HttpPost]
        public async Task<IActionResult> File(List<IFormFile> files)
        {
            long size = files.Sum(f => f.Length);


            var filePath = Path.GetTempFileName();


            foreach (var formFile in files)
            {
                if (formFile.Length > 0)
                {
                    using (var stream = new FileStream(filePath, FileMode.Create))
                    {
                        await formFile.CopyToAsync(stream);
                    }
                }
            }

            string fpath = filePath;

            var query = from d in db.TableA
                        where d.File == null && d.id == id // This is where I need to compare the ID
                        select d;


            foreach (TableA details in query)
            {
                details.File = filePath;
            }
            try
            {
                await db.SaveChangesAsync(); // await needed to hold execution
            }
            catch (Exception e)
            {
                Console.WriteLine(e);

            }


            return RedirectToAction("View");
        }

where d.File == null && d.id == id // This is where I need to compare the ID

多部分表格:

<form method="post" id="typea" enctype="multipart/form-data" asp-controller="Main" asp-action="File">
<label class="btn btn-info"> Upload your document <input type="file" name="files" onchange="this.form.submit()" hidden />
</label>
</form>

我的Ajax电话:

 $(document).ready(function () {
        $('#typea').click(function () {


            event.preventDefault();


            var $form = $(this);
            var serializedData = $form.serializeArray();
            serializedData.push({ name: "ID", value: "typea" });
            $.ajax({
                url: "Main/File",
                type: "POST",
                data: serializedData

            });

        });

我的问题是:

如果我推送数组,我不能指望 IFormFile 接口用于模型绑定。

我能否以某种方式扩展 IFormFIle 接口?

或者有什么方法可以不使用 IFormFile 来完成。 我尝试从 IFormFIle 接口编写我自己的模型引用但不能。

public interface IFormFile
{
    string ContentType { get; }
    string ContentDisposition { get; }
    IHeaderDictionary Headers { get; }
    long Length { get; }
    string Name { get; }
    string FileName { get; }
    Stream OpenReadStream();
    void CopyTo(Stream target);
    Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
}

我无法使用接口的方法,这是显而易见的。 请指点:).

  1. 您不需要实现(扩展)IFormFile 接口,组合包装优于继承。只需创建一个虚拟 POCO 来保存信息:

    public class IFormFilesWrapper{
    
        public string Id {get;set;}  // you might change the type to Guid / int /e.t.c
    
        public IList<IFormFile> Files {get;set;}
    }
    

    操作方法为:

    [HttpPost]
    public async Task<IActionResult> File(IFormFilesWrapper filesWrapper)
    {
        var id = filesWrapper.Id;  // here's the Id posted by client
    
        long size = filesWrapper.Files.Sum(f => f.Length);
    
        var filePath = Path.GetTempFileName();
    
        foreach (var formFile in filesWrapper.Files)
        {
            if (formFile.Length > 0)
            {
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await formFile.CopyToAsync(stream);
                }
            }
        }
    
        // ...
    }
    
  2. 附带说明一下,如果我没记错的话,$form.serializeArray() 不适用于 multipart/form-data。所以我使用普通的 FormData 来生成有效载荷:

    $(document).ready(function () {
        $('#typea>button').click(function () {
    
            event.preventDefault();
    
            var form = document.querySelector("#typea");
            var formData = new FormData(form);
            formData.append("ID","typea");
    
            var xhr = new XMLHttpRequest();
            xhr.open("POST","Main/File");
            xhr.send(formData);
        });
    });
    

截图: