如何在单个发布请求中传递多个文件和一个json对象

时间:2018-11-30 12:48:57

标签: javascript jquery asp.net-mvc

我挣扎了两天,但发现的解决方案还不够。这是场景:

我有.NET MVC项目,在当前视图中,用户可以通过单击“添加新行”来添加多行。每行包含4个输入type =“ text”和1个输入type =“ file”。一切正常。

当我将此表格发布到我的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中。结果未通过。不知道为什么。尝试了几乎所有类似递归函数的方法,以增加异步代码的延迟,直到我的对象被填满。但不行。

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

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

1 个答案:

答案 0 :(得分:0)

我运行了您的代码,修复了发现的一些错误,还修复了上载,它现在上载了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>