Upload Image Files in Asp.net Core via ajax
Tags: javascript, dotnet, csharp, webdev
Published: 2021-10-31 15:11:52

Upload image is a common feature for any webapplication. So here in this article, we are going to learn how using IFormFile we can upload files in Asp.net Core 3.1 also without using form tag, by just making an ajax post request on file selection i.e.(on input change event). 

Well, there was one requirement, where I have to upload files on input selection, and without a form tag and no submit button. I didn't find any article on this. So I just tried something simple and it's worked for me and hence sharing here a complete article on it.

##What is IFormFile?
**IFormFile** is an interface that is introduced in Asp.net Core 1.0. IFormFile interface is used to send files in the HTTP request. To use IFormFile we need to add namespace Microsoft.AspNetCore.Http in our PageModel.

[IFormFile](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.iformfile?view=aspnetcore-3.0) provides us useful properties like FileName, Length ,ContentType, ContentDisposition etc. It has methods as **CopyTo()**, **CopyToAsync()** which we going to use further in this article to save uploaded files.

##Step to upload file in asp.net core
1.Add HTML markup on the razor page.
2.Server-side: code to save the image using IFormFile.
3.jQuery Ajax call to upload a file on the server.

##Add HTML markup on the razor page.
First, we create a new Asp.net Core project, and open Index.cshtml which is the default page of our application. Now we simply add the input file tag and a button tag (optional) on our razor page.  

So finally our Razor page markup looks like as written below:
```
 <div class="row">       
	<h2>Upload file using jQuery ajax in Asp.net Core Razor Pages</h2>
   
	<div class=" form-group  text-center offset-3">
		<div class="custom-file">
			<input type="file" id="fileUpload" class="fileUpload">
			<button id="btnUpload" class="btn btn-success">Upload</button>
		</div>
	</div>
</div> 
```


##Server-side: Code to save the image using IFormFile
In asp.net core by default all static files are stored in [wwwroot folder](https://codepedia.info/get-image-file-from-wwwroot-folder-aspnet-core).As we need to access the wwwroot folder, hence we have to inject [IWebHostEnvironment](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostenvironment?view=dotnet-plat-ext-5.0) on razor PageModel.

Next, we add OnPostMyUploader() method, which handles the jQuery ajax post request. 
Our PageModel code looks like as written below:
```
public class IndexModel : PageModel
{        
	private readonly IWebHostEnvironment webHostEnvironment;
	
	public IndexModel(IWebHostEnvironment webHostEnvironment)
	{
		this.webHostEnvironment = webHostEnvironment;
	}

	public IActionResult OnPostMyUploader(IFormFile MyUploader)
	{
		if (MyUploader != null)
		{
			string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "mediaUpload");
			string filePath = Path.Combine(uploadsFolder, MyUploader.FileName);
			using (var fileStream = new FileStream(filePath, FileMode.Create))
			{
				MyUploader.CopyTo(fileStream);
			}
			return new ObjectResult(new { status = "success" });
		}
		return new ObjectResult(new { status = "fail" });

	}
} 
```
And our Startup.cs code look like
```
public void ConfigureServices(IServiceCollection services)
{
	services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
	services.AddControllersWithViews();
	services.AddRazorPages();
}
```

##jQuery Ajax: Create an ajax post request to upload files.
Here on file change event we create an object of FormData() and append files to it. Next, we make a post request to send those files.

Also at beforeSend, we added a request header with __RequestVerificationToken value, this is a hidden field that is auto-generated by **@Html.AntiForgeryToken()**.

The final js code to make an ajax request to upload file in asp.net core looks like as written below:
```
 $("#fileUpload").on('change', function () {
	var files = $('#fileUpload').prop("files");                
	var url = "/Index?handler=MyUploader";
	formData = new FormData();
	formData.append("MyUploader", files[0]);

	jQuery.ajax({
		type: 'POST',
		url: url,
		data: formData,
		cache: false,
		contentType: false,
		processData: false,
		beforeSend: function (xhr) {
			xhr.setRequestHeader("XSRF-TOKEN",
				$('input:hidden[name="__RequestVerificationToken"]').val());
		},
		success: function (repo) {
			if (repo.status == "success") {
				alert("File : " + repo.filename + " is uploaded successfully");
			}
		},
		error: function() {
			alert("Error occurs");
		}
	});
}); 

// If you want to upload file on button click, then use below button click event
$("#btnUpload").on('click',function(){
   // add jQuery ajax code to upload
});
```
Note: Make sure processData and contentType property is set as false.

**Conclusion:** Using IFromfile and jQuery ajax we were able to upload files on the server. Also for security reasons to protect from CSRF attacks, we added AddAntiforgery in our startup.cs file.

Article originally published at Codepedia.info [Asp.net Core: jQuery ajax file upload in Razor Pages (without form submit)](https://codepedia.info/ajax-file-upload-aspnet-core-razor-pages)