Document upload inside a form

0

I have several tabs in the html , and all those tabs are contained within one form. On the save button click, which is outside all tabs, it serializes all the data in all forms fields in the tabs and sends to database. All the tabs contains normal textbox and checkboxes.

   <div id="TabBtns" class="col-12 p-0">
   <button type="button" class="btn btn-secondary  mt-3">Tab1 </button>
   <button type="button" class="btn btn-secondary  mt-3">Tab2</button>
   <button type="button" class="btn btn-secondary  mt-3">Tab3</button>
   ...   

In one of the tabs I need to add a functionality so that user can upload a document and display the success message that file is uploaded along with the file name. so, I have created this form –

 <div class="card mb-2">
 <a class="collapsed card-link" data-toggle="collapse" id="uploadDocs" href="#Documents">
     <div class="card-header">
         Documents
         <em class="fa pull-right fa-chevron-up"></em>
     </div>
 </a>
 <div id="Documents" class="collapse">
     <div class="card-body">
         <input type="hidden" asp-for="@Model.UploadedBy" />
        
         <input type="hidden" asp-for="@Model.Uri" />
       
         <form id="uploadDocs">
             <div class="col-12">
                 <div class="row">

                     <div class="col-sm-6 col-lg-4">
                         <label asp-for="@Model.documentViewModel.DocumentName">Document Name*</label>
                         <input asp-for="@Model.documentViewModel.DocumentName" type="text" class="form-control" />
                         <span asp-validation-for="@Model.documentViewModel.DocumentName" class="text-danger field-validation-error"></span>
                     </div>
                    


                     <div class="col-sm-6 col-lg-4">
                     </div>
                     <div class="col-sm-6 col-lg-4">
                         <label>Document</label>
                         <div class="custom-file">
                             <input type="file" class="custom-file-input" asp-for="@Model.documentViewModel.FileName">
                             <span asp-validation-for="@Model.documentViewModel.FileName"></span>
                             <label class="custom-file-label" for="FileName" id="lblFileName">Choose file</label>
                         </div>
                     </div>

                 </div>
             </div>


             <div class="mt-2 mb-3">
                 <div class="col-12 text-right">

                     <button type="button" class="btn btn-primary float-right" id="UploadDoc" title="">Upload</button>
                     <button type="button" class="btn btn-outline-primary mr-3" id="ClearDoc">Clear</button>
                 </div>
             </div>



             

             <div class="mt-3">
                 <div class="col">
                     <div class="table-responsive">
                         <table id="tblfileDoc" class="table table-sm table-hover display" width="100%" cellspacing="0">
                             <thead>
                                 <tr>
                                     <th>Id</th>
                                     <th>Document Name</th>
                                     <th>Updated Date</th>
                                     <th class="text-center" width="100">Action</th>
                                 </tr>
                             </thead>

                         </table>
                     </div>
                 </div>
             </div>
         </form>
     </div>
 </div>

I am trying to write the code in jquery to do ajax call to the controller that will process file, upload file to cloud as a blob and return filename.But , since I cannot use form within a form to upload a document by user, I use FormData in jquery . But I am getting failed to load resource Error 500 when I check console log while running the app. And the controller action method is not hit through the ajax call. What am I doing wrong here ?

jquery method –

$('body').on('click', '#UploadDoc', function (e) {
e.preventDefault();
debugger;
//console.log('Upload button clicked');
var btnCaption = $(this).text();
if (btnCaption == "Upload") {

    $('#FileName').rules("add", {
        required: true,
        messages: {
            required: "Please choose document to upload.",

        }
    });
}
else {

    $("#FileName").rules("remove");
}


var fileData = $("#documentViewModel_FileName").prop('files')[0];
var formData = new FormData();
formData.append('file', fileData);
formData.append('documentName', $("#documentViewModel_DocumentName").val());

formData.append('DocumentType', $("#documentViewModel_DocumentType").val());
formData.append('UploadedBy', $("#documentViewModel_DocumentType").val());
debugger;
console.log(formData);

for (var key of formData.entries()) {
    console.log(key[0] + ', ' + key[1]);
}




$.ajax({
    url: "/Controller/SaveDoc",
    type: "POST",
    processData: false,
    beforeSend: function () {
        $(".page-loader").css("display", "block");
    },
    data: formData,
    success: function () {
        console.log('success data file');
    },
    error: function (jqXHR, textStatus, errorThrown) {
        if (jqXHR.status == 400) {
            LogoutForSessionExpiration();
        } else {
            $(".page-loader").css("display", "none");
            toastr.error("Error Occurred");
        }
    }
});
});

controller method –

 [HttpPost]
 public JsonResult SaveDoc(DocumentViewModel DocumentViewModel)
 {
     JsonResponse jsonResponse;
     bool result;
     try
 {
     DocumentViewModel model = new DocumentViewModel();

     if (DocumentViewModel.DocumentId == Guid.Empty)
     {
         var file = Request.Form.Files[0];
         var fileExtension = Path.GetExtension(file.FileName);
         DocumentViewModel.FileName = Path.GetFileNameWithoutExtension(file.FileName) + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + fileExtension;
         DocumentViewModel.DocumentByte = ConvertToBytes(file);

         var blob = _userService.UploadDocs(DocumentViewModel).Result;

         if (blob.Uri != null)
         {
             DocumentViewModel.Uri = blob.Uri.ToString();
             result = _userService.AddDocs(DocumentViewModel);
             if (result)
             {
                 jsonResponse = new JsonResponse();
                 jsonResponse.Status = ResponseStatus.OK.ToString();
                 jsonResponse.Message = "Document uploaded successfully.";
                 return Json(jsonResponse);
             }
             else
             {
                 jsonResponse = new JsonResponse();
                 jsonResponse.Status = ResponseStatus.ERROR.ToString();
                 jsonResponse.Message = "Error in uploading document.";
                 return Json(jsonResponse);
             }
         }
         else
         {
             jsonResponse = new JsonResponse();
             jsonResponse.Status = ResponseStatus.ERROR.ToString();
             jsonResponse.Message = "Error in uploading document.";
             return Json(jsonResponse);
         }
     }
     else
     {
         if (Request.Form.Files.Count > 0)
         {
             var file = Request.Form.Files[0];
             _userService.RemoveDocs(DocumentViewModel);
             var fileExtension = Path.GetExtension(file.FileName);
             DocumentViewModel.FileName = Path.GetFileNameWithoutExtension(file.FileName) + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + fileExtension;
             DocumentViewModel.DocumentByte = ConvertToBytes(file);
             var blob = _userService.UploadDocs(DocumentViewModel).Result;
             if (blob.Uri != null)
             {
                 DocumentViewModel.Uri = blob.Uri.ToString();
                 result = _userService.UpdateDocs(DocumentViewModel, true);
                 if (result)
                 {
                     jsonResponse = new JsonResponse();
                     jsonResponse.Status = ResponseStatus.OK.ToString();
                     jsonResponse.Message = "Document uploaded successfully";
                     return Json(jsonResponse);
                 }
                 else
                 {
                     jsonResponse = new JsonResponse();
                     jsonResponse.Status = ResponseStatus.ERROR.ToString();
                     jsonResponse.Message = "Error in uploading document.";
                     return Json(jsonResponse);
                 }
             }
             else
             {
                 jsonResponse = new JsonResponse();
                 jsonResponse.Status = ResponseStatus.ERROR.ToString();
                 jsonResponse.Message = "Error in uploading document.";
                 return Json(jsonResponse);
             }
         }
         else
         {
             //with no doc attched
             result = _userService.UpdateDocs(documentViewModel, false);
             if (result)
             {
                 jsonResponse = new JsonResponse();
                 jsonResponse.Status = ResponseStatus.OK.ToString();
                 jsonResponse.Message = "Signed doc. info updated successfully";
                 return Json(jsonResponse);
             }
             else
             {
                 jsonResponse = new JsonResponse();
                 jsonResponse.Status = ResponseStatus.ERROR.ToString();
                 jsonResponse.Message = "Error in updating signed doc. info.";
                 return Json(jsonResponse);
             }
         }
     }
 }
 catch (Exception ex)
 {
     _logger.LogError(ex.Message);
     jsonResponse = new JsonResponse();
     jsonResponse.Status = ResponseStatus.ERROR.ToString();
     jsonResponse.Message = "Error in uploading document";
     return Json(jsonResponse);
 }

}

viewmodel for document tab is nested inside the viewmodel of parent page.

ViewModel class –

using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Text;

namespace App
{
    public class DocumentViewModel
    {
    public Guid DocumentId { get; set; }
   
   
    public string DocumentName { get; set; }
    public string DocumentType { get; set; }
    
    public string UploadedBy { get; set; }
    public string FileName { get; set; }
    public string Uri { get; set; }
    public byte[] DocumentByte { get; set; }
      
}

}