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

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

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

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

我要发布到的控制器:

 [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");
        }



其中d.File == null && d.id == id //这是我需要比较的地方
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);
}


我不能使用接口的方法,这很明显。
请指针:)。

最佳答案

您不需要实现(扩展)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);
            }
        }
    }

    // ...
}

附带说明一下,如果我没记错的话,$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);
    });
});



屏幕截图:

jquery - 如何在.NET Core中扩展并添加到IFormFile接口(interface)。提交ajax请求时需要将数据附加到序列化数组-LMLPHP

08-15 19:42