【问题标题】:How to pass raw complex object to MVC action?如何将原始复杂对象传递给 MVC 动作?
【发布时间】:2019-05-27 07:21:25
【问题描述】:

问题:无法将 File 对象解析为 JSON 字符串,这样做时只会获取空值,同时尝试将复杂类型发送到 MVC 控制器。

我尝试将它添加到 FormData 对象中并将其传递给控制器​​,但是,传递它们的列表并不成功,因为它要么返回一个空数组,要么只是简单的 null

型号:

public class UploadedDocument
    {

        public HttpPostedFile File { get; set;}
        public string DocumentId { get; set;}
        public string DocumentType { get; set; }

    }

控制器:

        [HttpPost]
        [ActionName("UploadFile")]
        public ActionResult Upload(IEnumerable<UploadedDocument> documents)
        {
            return View();
        }

上传功能:

var _documents = [];

                for (var i = 0; i < arrayOfFiles.length; i++) {

                    var document = {
                        "File": arrayOfFiles[i].file,
                        "DocumentId": arrayOfFiles[i].documentId,
                        "DocumentType": arrayOfFiles[i].documentName
                    };

                    _documents.push(document);
                }

                $.ajax({
                    url: "@Url.Action("UploadFile", "Home")",
                    type: "POST",
                    data: {"documents":_documents}
                    });
            }
        });

【问题讨论】:

  • 在你的 ajax 调用中试试这个:data: JSON.stringify({ _documents }),
  • @user1987392 你看,这就是问题所在,JSON.stringify() 不能用于 File 对象(不记得为什么),当我这样做时它只返回和空数组
  • 在你的 AJAX data: JSON.stringify(_documents, null, 4) 中替换它,它会正常工作
  • @KunalMukherjee 我试过了,但控制器收到一个空值
  • 我很确定你需要使用 FormData 来让它工作

标签: c# jquery ajax model-view-controller


【解决方案1】:

基本上,我设法通过 ajax 处理单个上传,如下所示

输入元素

  <input type="file" name="customerpicture" id="customerpicture" />

表单数据

 function getFormData() {
        var data = new FormData();
        var files = $("#customerpicture").get(0).files;
        if (files.length > 0) {
            data.append("file", files[0]);
        }
        //data.append("Name", $("#name").val());

        return data;
    }

Ajax 方法

$('#InsertCustomer').click(function () {
        debugger;
            var antiForgeryToken = $("input[name=__RequestVerificationToken]").val();
            var url = '@Url.Action("Add_Customer", "Customer")';

                $.ajax({
                    type: 'POST',
                    headers: { "__RequestVerificationToken": antiForgeryToken },
                    url: url,
                    contentType: false,
                    processData: false,
                    data: getFormData(),
                    success: function (res) {
                            $('#custinsertmodal').modal('hide');
                            $('#custinsertmodal').find("input,textarea,select")
                                .val('')
                                .end()
                                .find("input[type=checkbox], input[type=radio]")
                                .prop("checked", "")
                                .end();
                            bootbox.alert({ message: res.result });   
                    }
                });     
        });

控制器

 [HttpPost, ValidateHeaderAntiForgeryToken]
    public JsonResult Add_Customer()
    {
        var errMsg = string.Empty;
        byte[] tmpImage;
        try
        {
            //Customer Image Processing
            var file = Request.Files.Get("file");

            if (file != null && file.ContentLength > 0)
            {
                //Image Saving to Folder
                UploadHelper.UploadFile(file);

                //Image Saving to Database
                tmpImage = new byte[file.ContentLength];
                file.InputStream.Read(tmpImage, 0, file.ContentLength);

                CustomerModel model = new CustomerModel
                {

                    Signature = tmpImage
                };
                _setupRepo.CreateSignatory(model);
                return Json(new { error = false, result = $"Customer was successfully created" }, JsonRequestBehavior.AllowGet);

        }
        catch (Exception ex)
        {
            errMsg = ex.Message.ToString();
            return Json(new { error = true, result = errMsg }, JsonRequestBehavior.AllowGet);
        }
    }

【讨论】:

  • 出于某种原因,var file 对我来说设置为 null,即使我为我的应用程序定制了它
【解决方案2】:

如果您想专门使用 ajax 调用来上传文件:您需要使用 FormData 对象。文件必须作为 FormData 对象中的单个项目发送,因此不能作为列表的一部分传递给您的 ActionResult。

假设您的页面上有动态数量的文件输入,其中包含用户可以填写的自定义字段,您的代码可能如下所示:

HTML / Javascript:

<form id="File_Form">
    <input type="file" name="File_1" />
    <input type="text" name="DocumentName_File_1" value="doc1" />
    <input type="text" name="DocumentId_File_1" value="1" />

    <input type="file" name="File_2" />
    <input type="text" name="DocumentName_File_2" value="doc2" />
    <input type="text" name="DocumentId_File_2" value="2" />

    <button>Upload Files</button>
</form>

<script>
    $("#File_Form").submit(function() {
        var formData = new FormData(this);

        $.ajax({
            url: '@Url.Action("UploadFiles")',
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            cache: false
        });

        return false;
    });
</script>

C#:

[HttpPost]
public ActionResult UploadFiles() {
    foreach (string fileName in Request.Files) {
        HttpPostedFileWrapper file = Request.Files[fileName];
        string documentName = Request.Form[$"DocumentName_{fileName}"]?.ToString();
        string documentId = Request.Form[$"DocumentId_{fileName}"]?.ToString();

        // Do things with your file here.
    }
    return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}

它可能不会自动序列化到您的模型对象中,但您仍然可以通过巧妙地命名表单元素来获得您想要的结果。

【讨论】:

    【解决方案3】:

    试试这个。 var _documents = [];

                    for (var i = 0; i < arrayOfFiles.length; i++) {
    
                        var document = {
                            "File": arrayOfFiles[i].file,
                            "DocumentId": arrayOfFiles[i].documentId,
                            "DocumentType": arrayOfFiles[i].documentName
                        };
    
                        _documents.push(document);
                    }
    
    var formData = new FormData();
    formData.append("documents", documents);
    
                    $.ajax({
                        url: "@Url.Action("UploadFile", "Home")",
                        type: "POST",
                        data: formData,
                        processData: false,
                        contentType: false,
                    });
                }
            });
    

    【讨论】:

    • 可悲的是,我以前试过这个,它发送一个空数组/列表
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 2013-02-26
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多