如何将原始复杂对象传递给MVC操作?

时间:2019-05-27 07:21:25

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

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

我尝试将其添加到FormData对象中并传递给控制器​​,但是,传递它们的List并不成功,因为它会返回一个空数组或只是纯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}
                    });
            }
        });

3 个答案:

答案 0 :(得分:0)

基本上,我设法通过如下所示的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);
        }
    }

答案 1 :(得分:0)

尝试一下。    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,
                });
            }
        });

答案 2 :(得分:0)

如果要专门使用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);
}

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