1

I'm using .NET Core 6 (not MVC though). I'm trying to upload a file using AJAX that will also allow me to show a progress bar. I had this working in a PHP solution but carrying over to C# is proving to be difficult. Hoping someone can assist me.

I can see from the console that it's posting the file and sending everything however in C# I'm a bit lost on how to receive it. No matter what I've tried it's always null. Ultimately I'll be saving it as bytes to the db but it's important to have the ability to show progress of the upload.

The HTML

<input type="file" id="uploaddoc" style="display: none;" accept=".doc, .docx, .pdf, .png, .jpg, .jpeg" />
<input type="button" value="Browse..." class="btn btn-primary" style="max-width: 150px;"
     onclick="document.getElementById('uploaddoc').click();" />
<div class="progress" id="progCollapse" style="position: absolute; height: 10px; 
     width: 425px; margin-left: -15px; margin-top: 5px; display: none">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
     id="progress" style="width: 0" aria-valuenow="0" aria-valuemin="0"
     aria-valuemax="100"></div></div>

The javascript

function uploadDoc() {
  let file = document.getElementById("uploaddoc").files;
  let data = { filename: this.value }

  if (file.length > 0) {
     let fileToLoad = file[0];
     let fileReader = new FileReader();

     $("#progCollapse").show()
     document.getElementById("progress").style.width = "0%"
     fileReader.onload = function (fileLoadedEvent) {
     data.file = fileLoadedEvent.target.result;

     $.ajax({
        xhr: function () {
        let xhr = new window.XMLHttpRequest();
        xhr.upload.addEventListener("progress", function (evt) {
           if (evt.lengthComputable) {
              let percentComplete = evt.loaded / evt.total;
              document.getElementById("progress").style.width = percentComplete * 100 + "%"
              if (percentComplete === 1) {
                 $("#progCollapse").hide()
                 document.getElementById("progress").style.width = "0%"
              }
           }
         }, false);
         xhr.addEventListener("progress", function (evt) {
            if (evt.lengthComputable) {
               let percentComplete = evt.loaded / evt.total;
                  document.getElementById("progress").style.width = "100%"
            }
         }, false);
         return xhr;
         },
         beforeSend: function (xhr) {
           xhr.setRequestHeader("XSRF-TOKEN",
           $('input:hidden[name="__RequestVerificationToken"]').val());
         },
         type: 'POST',
         url: "/PageName?handler=SaveFile",
         contentType: false,
         processData: false,
         data: { doc: fileReader.result },
         success: function (data) {
         }
     });
    };
  fileReader.readAsDataURL(fileToLoad);
}
}

The C#

public OnPostSaveFile() 
{
    // This is where I'm stuck, what do I enter to receive the file correctly?
    // I'm going to be converting it to bytes to save to the db
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

0

It kind of sounds like you're using Razor pages. If that is the case, try this tutorial on uploading files to Razor pages:

https://www.learnrazorpages.com/razor-pages/forms/file-upload


    private IHostingEnvironment Environment;
    public string Message { get; set; }
 
    public IndexModel(IHostingEnvironment _environment)
    {
        Environment = _environment;
    }
 
    public void OnGet()
    {
 
    }
 
    public void OnPostUpload(List<IFormFile> postedFiles)
    {
        string wwwPath = this.Environment.WebRootPath;
        string contentPath = this.Environment.ContentRootPath;
 
        string path = Path.Combine(this.Environment.WebRootPath, "Uploads");
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
 
        List<string> uploadedFiles = new List<string>();
        foreach (IFormFile postedFile in postedFiles)
        {
            string fileName = Path.GetFileName(postedFile.FileName);
            using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create))
            {
                postedFile.CopyTo(stream);
                uploadedFiles.Add(fileName);
                this.Message += string.Format("<b>{0}</b> uploaded.<br />", fileName);
            }
        }
    }

You'll have to adjust to save the bytes wherever you need to.

Bron Davies
  • 5,930
  • 3
  • 30
  • 41
  • Thanks, yes I had seen and tried that example. It calls the method correctly but the upload value is null. – Stephan Young Aug 31 '22 at 15:15
  • I think your jQuery isn't submitting the files correctly. The easiest way to submit a form with jQuery that has files is to use `FormData` like this: https://stackoverflow.com/questions/5392344/sending-multipart-formdata-with-jquery-ajax – Bron Davies Aug 31 '22 at 16:08
  • That makes sense. I can see that it's posting all the values now but then that takes me back to my original question. Everything is showing as null in my C# method. What should that look like to allow me to receive the data? Every example I've tried is the same result or everything is designed for MVC and older versions. – Stephan Young Aug 31 '22 at 17:11
  • Your code in your questions is `public void OnPostSaveFile()` Have you tried using the example above? `public void OnPostUpload(List postedFiles)` – Bron Davies Aug 31 '22 at 17:16
  • Yes and it returns null. I copied and pasted that entire example to test and didn't work. – Stephan Young Aug 31 '22 at 17:27