【问题标题】:how to pass multiple files and a json object in single post request如何在单个发布请求中传递多个文件和一个 json 对象
【发布时间】:2019-05-02 15:09:45
【问题描述】:

我挣扎了两天,但没有找到完全解决方案。这是场景:

我有 .NET MVC 项目,在当前视图中,用户可以通过单击“添加新行”来添加多行。每行包含 4 个输入类型 =“文本”和 1 个输入类型 =“文件”。它工作得很好。

当我将此表单发布到我的 MVC 控制器时,问题正在发生。我在我的 MVC 控制器上接收所有数据,除了在每一行中上传的文件。我就是这样做的。

查看:

<div class="row p-t-20">
 <div class="col-md-2">
 <div class="form-group">
 <label class="control-label">Transaction Date</label>
 <input type="text" name="TransactionDate1" id="mdate1" class="form-control tdate01" value="" required />
 </div>
 </div>
 
 <div class="col-md-2">
<div class="form-group">
<label class="control-label">Description</label>
<textarea name="Description1" id="Description1" class="form-control descr01" cols="2" rows="2"></textarea>
</div>
</div>

 <div class="col-md-1">
<div class="form-group">
 <label class="control-label">Amount</label>
<input type="text" name="Amount1" id="Amount1" class="form-control amt01" required />
 </div>
 </div>

 <div class="col-md-1">
 <div class="form-group">
 <label class="control-label">Invoice #</label>
 <input type="text" name="InvoiceNo1" id="InvoiceNo1" class="form-control inv01" required />
 </div>
 </div>

 <div class="col-md-2">
 <div class="form-group">
 <label class="control-label">Comments</label>
<textarea name="Comments1" id="Comments1" class="form-control comm01" cols="1" rows="2"></textarea>
 </div>
</div>

 <div class="col-md-2">
 <div class="form-group">
 <label>Upload Invoice</label>
<input type="file" name="postedFile1"  id="postedFile1" class="form-control file01" required />
 <input type="hidden" name="hiddenfile1" id="hiddenfile1" value=""/>
</div>
</div>

 <div class="col-md-2">
<div class="form-group">
 <br />
<input type="button" id="btnAdd" value="+ Row" class="btn btn-dark" />
 </div>
 </div>
 </div>
 <div class="form-actions m-t-40">
 **<button type="button" id="btnSubmit" class="btn btn-success"> <i class="fa fa-check"></i> Save</button>**
</div>

jQuery 代码

var rowCount; var transactionDetailVM = []; var ClaimTransactionVM = {}; var reimFiles = []; var fileString = ''; var reader;
$(document).ready(function () {
    debugger;
    rowCount = 1;
    $(document).on("click", "#btnAdd", function () { //
       // var rowCount = $('.data-contact-person').length + 1;
        //Generating base64 string for previously uploaded file.
        //var filelogoUpload = $('#postedFile' + rowCount).get(0);
        //var files = filelogoUpload.files;
        //var file = files[0]; getBase64(file, rowCount);
        rowCount++;
        //Validations will run before adding a new row.
        var rowdiv = '<div class="row p-t-20">'         
           + '<div class="col-md-2">              '
            + ' <div class="form-group">          '
            + '  <label class="control-label">Transaction Date</label>'
            + ' <input type="text" name="TransactionDate' + rowCount + '" id="mdate' + rowCount +'" class="form-control tdate01" value="" required />'
            + '  </div>'
            + ' </div>'
            + '<div class="col-md-2" >'
            + ' <div class="form-group">'
            + ' <label class="control-label">Description</label>'
            + '<textarea name="Description' + rowCount +'" id="Description' + rowCount +'" class="form-control descr01" cols="2" rows="2"></textarea>'
            + '</div>'
            + '</div>'                       
            + '<div class="col-md-1">'
            + '<div class="form-group">'
            + '<label class="control-label">Amount</label>'
            + ' <input type="text" name="Amount' + rowCount + '" id="Amount' + rowCount +'" class="form-control amt01" />'
            + '</div>'
            + '</div>'
            + '<div class="col-md-1" >'
            + '<div class="form-group">'
            + '<label class="control-label">Invoice #</label>'
            + '<input type="text" name="InvoiceNo' + rowCount + '" id="InvoiceNo' + rowCount +'" class="form-control inv01" />'
            + '</div>'
            + '</div>'
            + '<div class="col-md-2" >'
            + '<div class="form-group">'
            + '<label class="control-label">Comments</label>'
            + '<textarea name="Comments' + rowCount +'" id="Comments' + rowCount +'" class="form-control comm01" cols="1" rows="2"></textarea>'
            + ' </div></div>'
            + '<div class="col-md-2">'
            + '<div class="form-group">'
            + ' <label>Upload Invoice</label>'
            + '<input type="file" name="postedFile' + rowCount + '" id="postedFile' + rowCount + '" class="form-control file01" />'
            //+ '<input type="hidden" name="hiddenfile' + rowCount + '" id="hiddenfile' + rowCount+'"/>'
            + '</div>'
            + '</div>'
            + '<div class="col-md-2">'
              +'<div class="form-group">'
            + '<input type="button" id="btnAdd" value="+ Row" class="btn btn-dark" />'
            + '<input type = "button" id ="btnRemove" value="- Row" class="btn btn-danger" />'
              +'</div>'
              +'</div>'
              +'</div>';
        $('#newClaimForm').append(rowdiv);
        debugger;
       
        //$("input[name*='TransactionDate']").css("background-color", "yellow");
        // Adding these controls to Main table class
    });
});  

$(document).on("click", "#btnRemove", function () {
    $(this).closest("div[class='row p-t-20']").remove();
});

function getAllData() {
    console.log('getalldata called');
    var claimTitle = $('#TransactionName').val();
    var claimType = $('#ClaimTypes').val();
    //Transaction Details
    for (var i = 1; i <= rowCount; i++) {
        //file operation
        var filelogoUpload = $('#postedFile' + i).get(0);
        var files = filelogoUpload.files;
        var file = files[0]; //getBase64(file);
        //reader = new FileReader();
        //reader.onload = function () {
        //    //console.log(reader.result);
        //    fileString = reader.result;
        //};
        //reader.readAsDataURL(file);
        //end file operation
        var trandate = $('#mdate' + i).val();
        var descr = $('#Description' + i).val();
        var amt = $('#Amount' + i).val();
        var invno = $('#InvoiceNo'+i).val();
        var comm = $('#Comments' + i).val();
        //var baseFileString = $('#hiddenFile' + i).val();
       
        debugger;
        
        console.log(trandate);
        console.log(descr);
        console.log(amt);
        console.log(invno);
        console.log(comm);
        console.log(file);
       

        
        var transactionDetails = {
            TransactionDate: trandate,
            Description: descr,
            Amount: amt,
            InvoiceNumber: invno,
            Comments: comm,
            baseFile: file
        }
        //console.log('Transaction Object:' + transactionDetails);
         //filled transaction Detail array
        transactionDetailVM.push(transactionDetails);
        console.log(transactionDetailVM);
        //reimFiles.push(file);
    }
        //filled model
        ClaimTransactionVM = {
            TransactionName: claimTitle,
            ClaimType: claimType,
            TransactionDetails: transactionDetailVM
        };
        //  console.log('Model:'+ClaimTransactionVM);
    }


$("#btnSubmit").click(function SaveReimbursements() {
    //Validations will run
    console.log('Save button called');
    debugger;
    getAllData();
    if (ClaimTransactionVM !== null) {
        var FormClaims = new FormData();
        FormClaims.append('currentClaim', JSON.stringify(ClaimTransactionVM));
        //FormClaims.append()
        //console.log(ClaimTransactionVM);
        //var data = {
        //    currentClaim: ClaimTransactionVM, 
        //    files: reimFiles
        //}
        $.ajax({
            url: '/ClaimProcess/CreateClaim',
            type: 'POST',
            processData: false,
            contentType: 'application/json',
            data: FormClaims,//JSON.stringify(ClaimTransactionVM),
            success: function (response) {
                if (response === true) {
                    console.log('Success: IsSuccess True called');
                    swal({
                        title: 'success',
                        text: "Claim Added Successfully.",
                        type: "success",
                        confirmButtonColor: "#007AFF"
                    });
                }
                else if (response === false) {
                    console.log('Success: IsSuccess False called');
                    swal({
                        title: "Error!",
                        text: '',
                        type: "warning",
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: "Ok"
                    });
                }

            }
        });
       
    }
    else
        console.log('Model is empty.')

});

我需要传递的最终 JSON 对象是“ClaimTransactionVM”,它携带交易详细信息列表(动态添加的每一行)和一些其他参数。

我已经尝试过以下事情:

  1. 使用的 var reader = new FileReader();并将文件转换为 base64 字符串并将其传递给 Json 对象。它在调试模式下工作得很好,但在实时 reader.result 中没有通过。不知道为什么。尝试了几乎所有方法,例如循环函数来为异步代码添加延迟,直到我的对象被填满。但是不行。

  2. 表单数据:使用 JSON.stringify 转换最终的 Json 对象,它确实通过了,但 File 没有转换为 HTTPPostedFileBase 对象。它在收到其他参数时跳过文件。

我想知道如何在我的 POST 调用中一起发送多个文件和这个 JSON 对象。

【问题讨论】:

    标签: javascript jquery asp.net-mvc


    【解决方案1】:

    我运行了您的代码,修复了一些注意到的错误并修复了上传,它现在上传了一个 base64 字符串。在您的 .NET MVC 中,您更改句柄 base64 字符串并将其保存为文件。

    更新代码:

    var rowCount; var transactionDetailVM = []; var ClaimTransactionVM = {}; var reimFiles = []; var fileString = ''; var reader; var preview = '';
    $(document).ready(function () {
        rowCount = 1;
        $("#btnAdd").click(function () { //
            rowCount++;
            //Validations will run before adding a new row.
            var rowdiv = '<div class="row p-t-20">'         
               + '<div class="col-md-2">              '
                + ' <div class="form-group">          '
                + '  <label class="control-label">Transaction Date</label>'
                + ' <input type="text" name="TransactionDate' + rowCount + '" id="mdate' + rowCount +'" class="form-control tdate01" value="" required />'
                + '  </div>'
                + ' </div>'
                + '<div class="col-md-2" >'
                + ' <div class="form-group">'
                + ' <label class="control-label">Description</label>'
                + '<textarea name="Description' + rowCount +'" id="Description' + rowCount +'" class="form-control descr01" cols="2" rows="2"></textarea>'
                + '</div>'
                + '</div>'                       
                + '<div class="col-md-1">'
                + '<div class="form-group">'
                + '<label class="control-label">Amount</label>'
                + ' <input type="text" name="Amount' + rowCount + '" id="Amount' + rowCount +'" class="form-control amt01" />'
                + '</div>'
                + '</div>'
                + '<div class="col-md-1" >'
                + '<div class="form-group">'
                + '<label class="control-label">Invoice #</label>'
                + '<input type="text" name="InvoiceNo' + rowCount + '" id="InvoiceNo' + rowCount +'" class="form-control inv01" />'
                + '</div>'
                + '</div>'
                + '<div class="col-md-2" >'
                + '<div class="form-group">'
                + '<label class="control-label">Comments</label>'
                + '<textarea name="Comments' + rowCount +'" id="Comments' + rowCount +'" class="form-control comm01" cols="1" rows="2"></textarea>'
                + ' </div></div>'
                + '<div class="col-md-2">'
                + '<div class="form-group">'
                + ' <label>Upload Invoice</label>'
                + '<input type="file" onChange="startRead2(\'' + rowCount + '\')" name="postedFile' + rowCount + '" id="postedFile' + rowCount + '" class="form-control file01" />'
                + '<input type="hidden" name="hiddenfile' + rowCount + '" id="hiddenfile' + rowCount+'"/>'
                + '</div>'
                + '</div>'
                + '<div class="col-md-2">'
                  +'<div class="form-group">'
                + '<input type = "button" id ="btnRemove" value="- Row" class="btn btn-danger" />'
                  +'</div>'
                  +'</div>'
                  +'</div>';
            $('#newClaimForm').append(rowdiv);
            // debugger;
           
            //$("input[name*='TransactionDate']").css("background-color", "yellow");
            // Adding these controls to Main table class
        });
    });  
    
    $(document).on("click", "#btnRemove", function () {
        $(this).closest("div[class='row p-t-20']").remove();
    });
    
    function startRead2(id) {
           var file2 = document.getElementById('postedFile'+id);
           preview = id;
    
           if (!file2.files[0]) {
              return;
           }
           
           //add data type for upload validation
           if ((file2.files[0].type != 'image/jpeg') && (file2.files[0].type != 'image/jpg') && (file2.files[0].type != 'image/png')) {
              alert('File Type not Supported. File must be jpeg or png');
              file2.value = '';
              return;
           }
    
           let filex = file2.files[0];
           var reader2 = new FileReader();
           var reader_data2 = reader2.readAsDataURL(filex);
           reader2.onload = this.addImage2;
    }
    
    function addImage2(imgsrcs) {
           let hidden_bin = document.getElementById('hiddenfile'+preview);
           hidden_bin.value = imgsrcs.target.result;
    }
    
    function getAllData() {
        console.log('getalldata called');
        var claimTitle = $('#TransactionName').val();
        var claimType = $('#ClaimTypes').val();
        //Transaction Details
        for (var i = 1; i <= rowCount; i++) {
            var trandate = $('#mdate' + i).val();
            var descr = $('#Description' + i).val();
            var amt = $('#Amount' + i).val();
            var invno = $('#InvoiceNo'+i).val();
            var comm = $('#Comments' + i).val();
    
            var transactionDetails = {
                TransactionDate: trandate,
                Description: descr,
                Amount: amt,
                InvoiceNumber: invno,
                Comments: comm,
                baseFile: base64_file
            }
    
            transactionDetailVM.push(transactionDetails);
            console.log(transactionDetailVM);
        }
            //filled model
            ClaimTransactionVM = {
                TransactionName: claimTitle,
                ClaimType: claimType,
                TransactionDetails: transactionDetailVM
            };
    
        }
    
    
    $("#btnSubmit").click(function SaveReimbursements() {
        //Validations will run
        console.log('Save button called');
        // debugger;
        getAllData();
        if (ClaimTransactionVM !== null) {
            var FormClaims = new FormData();
            FormClaims.append('currentClaim', JSON.stringify(ClaimTransactionVM));
    
    
            $.ajax({
                url: '/ClaimProcess/CreateClaim',
                type: 'POST',
                processData: false,
                contentType: 'application/json',
                data: FormClaims,//JSON.stringify(ClaimTransactionVM),
                success: function (response) {
                    if (response === true) {
                        console.log('Success: IsSuccess True called');
                        swal({
                            title: 'success',
                            text: "Claim Added Successfully.",
                            type: "success",
                            confirmButtonColor: "#007AFF"
                        });
                    }
                    else if (response === false) {
                        console.log('Success: IsSuccess False called');
                        swal({
                            title: "Error!",
                            text: '',
                            type: "warning",
                            confirmButtonColor: "#DD6B55",
                            confirmButtonText: "Ok"
                        });
                    }
    
                }
            });
           
        }
        else
            console.log('Model is empty.')
    
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="row p-t-20">
     <div class="col-md-2">
     <div class="form-group">
     <label class="control-label">Transaction Date</label>
     <input type="text" name="TransactionDate1" id="mdate1" class="form-control tdate01" value="" required />
     </div>
     </div>
     
     <div class="col-md-2">
    <div class="form-group">
    <label class="control-label">Description</label>
    <textarea name="Description1" id="Description1" class="form-control descr01" cols="2" rows="2"></textarea>
    </div>
    </div>
    
     <div class="col-md-1">
    <div class="form-group">
     <label class="control-label">Amount</label>
    <input type="text" name="Amount1" id="Amount1" class="form-control amt01" required />
     </div>
     </div>
    
     <div class="col-md-1">
     <div class="form-group">
     <label class="control-label">Invoice #</label>
     <input type="text" name="InvoiceNo1" id="InvoiceNo1" class="form-control inv01" required />
     </div>
     </div>
    
     <div class="col-md-2">
     <div class="form-group">
     <label class="control-label">Comments</label>
    <textarea name="Comments1" id="Comments1" class="form-control comm01" cols="1" rows="2"></textarea>
     </div>
    </div>
    
     <div class="col-md-2">
     <div class="form-group">
     <label>Upload Invoice</label>
    <input type="file" name="postedFile1" onChange="startRead2('1')"  id="postedFile1" class="form-control file01" required />
     <input type="hidden" name="hiddenfile1" id="hiddenfile1" value=""/>
    </div>
    </div>
    	
    
    	<div id="newClaimForm"></div>
     <div class="col-md-2">
    <div class="form-group">
     <br />
    <input type="button" id="btnAdd" value="+ Row" class="btn btn-dark" />
     </div>
     </div>
     </div>
     <div class="form-actions m-t-40">
     **<button type="button" id="btnSubmit" class="btn btn-success"> <i class="fa fa-check"></i> Save</button>**
    </div>

    【讨论】:

    • 是的。有效。将它绑定在“OnChange”事件上是个好主意。非常感谢您花时间在这方面。我注意到一件奇怪的事情,当我使用 jQuery 读取隐藏字段的 base64 值时,它无法做到。但是当我使用纯 javascript 时,它起作用了。 jQuery: $('#hiddenFile' + i).val(); //不起作用。 Javascript: document.getElementById('hiddenfile' + i).value //确实有效 不知道为什么。
    • 很高兴它成功了。你注意到 jQuery 的地方很奇怪,但为了安全起见,只要在简单的任务上坚持纯 JavaScript,比如收集数据值和东西。
    猜你喜欢
    • 2013-10-26
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-11
    • 2015-04-01
    • 2015-10-16
    • 1970-01-01
    相关资源
    最近更新 更多