Added Async File Upload.
This commit is contained in:
47
Controllers/FilesController.cs
Normal file
47
Controllers/FilesController.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using CarCareTracker.External.Interfaces;
|
||||
using CarCareTracker.Models;
|
||||
using LiteDB;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
using System.Drawing;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CarCareTracker.Controllers
|
||||
{
|
||||
public class FilesController : Controller
|
||||
{
|
||||
private readonly ILogger<FilesController> _logger;
|
||||
private readonly IVehicleDataAccess _dataAccess;
|
||||
private readonly IWebHostEnvironment _webEnv;
|
||||
|
||||
public FilesController(ILogger<FilesController> logger, IWebHostEnvironment webEnv)
|
||||
{
|
||||
_logger = logger;
|
||||
_webEnv = webEnv;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult HandleFileUpload(IFormFile file)
|
||||
{
|
||||
var fileName = UploadImage(file);
|
||||
return Json(fileName);
|
||||
}
|
||||
|
||||
private string UploadImage(IFormFile fileToUpload)
|
||||
{
|
||||
string uploadDirectory = "images/";
|
||||
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
string fileName = Guid.NewGuid() + Path.GetExtension(fileToUpload.FileName);
|
||||
string filePath = Path.Combine(uploadPath, fileName);
|
||||
using (var stream = System.IO.File.Create(filePath))
|
||||
{
|
||||
fileToUpload.CopyTo(stream);
|
||||
}
|
||||
return Path.Combine("/", uploadDirectory, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,8 @@ namespace CarCareTracker.Controllers
|
||||
_webEnv = webEnv;
|
||||
}
|
||||
|
||||
public IActionResult Index(VehicleInputModel? initialModel)
|
||||
public IActionResult Index()
|
||||
{
|
||||
if (initialModel is not null && initialModel.Errors is not null)
|
||||
{
|
||||
return View(initialModel);
|
||||
}
|
||||
return View();
|
||||
}
|
||||
public IActionResult Garage()
|
||||
@@ -41,53 +37,19 @@ namespace CarCareTracker.Controllers
|
||||
return View();
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult AddVehicle(VehicleInputModel vehicleInput)
|
||||
public IActionResult AddVehicle(Vehicle vehicleInput)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
//validation
|
||||
if (vehicleInput.Year < 1900)
|
||||
errors.Add("Year is invalid");
|
||||
if (string.IsNullOrWhiteSpace(vehicleInput.Make))
|
||||
errors.Add("Make is required");
|
||||
if (string.IsNullOrWhiteSpace(vehicleInput.Model))
|
||||
errors.Add("Model is required");
|
||||
if (string.IsNullOrWhiteSpace(vehicleInput.LicensePlate))
|
||||
errors.Add("License Plate is required");
|
||||
if (errors.Any())
|
||||
{
|
||||
vehicleInput.Errors = errors;
|
||||
return RedirectToAction("Index", "Home", vehicleInput);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//map vehicleInput to vehicle object.
|
||||
var newVehicle = new Vehicle
|
||||
{
|
||||
Year = vehicleInput.Year,
|
||||
Make = vehicleInput.Make,
|
||||
Model = vehicleInput.Model,
|
||||
LicensePlate = vehicleInput.LicensePlate
|
||||
};
|
||||
if (vehicleInput.Image is not null)
|
||||
{
|
||||
string imagePath = UploadImage(vehicleInput.Image);
|
||||
if (!string.IsNullOrWhiteSpace(imagePath))
|
||||
{
|
||||
newVehicle.ImageLocation = imagePath;
|
||||
}
|
||||
}
|
||||
//save vehicle.
|
||||
var result = _dataAccess.SaveVehicle(newVehicle);
|
||||
RedirectToAction("Index");
|
||||
var result = _dataAccess.SaveVehicle(vehicleInput);
|
||||
return Json(result);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error Saving Vehicle");
|
||||
vehicleInput.Errors = new List<string> { "Error Saving Vehicle, Please Try Again Later" };
|
||||
return RedirectToAction("Index", "Home", vehicleInput);
|
||||
return Json(false);
|
||||
}
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
@@ -95,20 +57,5 @@ namespace CarCareTracker.Controllers
|
||||
{
|
||||
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
|
||||
private string UploadImage(IFormFile fileToUpload)
|
||||
{
|
||||
string uploadDirectory = "images/";
|
||||
string uploadPath = Path.Combine(_webEnv.WebRootPath, uploadDirectory);
|
||||
if (!Directory.Exists(uploadPath))
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
string fileName = Guid.NewGuid() + Path.GetExtension(fileToUpload.FileName);
|
||||
string filePath = Path.Combine(uploadPath, fileName);
|
||||
using (var stream = System.IO.File.Create(filePath))
|
||||
{
|
||||
fileToUpload.CopyTo(stream);
|
||||
}
|
||||
return Path.Combine("/", uploadDirectory, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class VehicleInputModel
|
||||
{
|
||||
public int Year { get; set; }
|
||||
public string Make { get; set; }
|
||||
public string Model { get; set; }
|
||||
public string LicensePlate { get; set; }
|
||||
public IFormFile Image { get; set; }
|
||||
public List<string> Errors { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
@{
|
||||
ViewData["Title"] = "My Garage";
|
||||
}
|
||||
@model VehicleInputModel
|
||||
@section Scripts{
|
||||
@section Scripts {
|
||||
<script src="~/js/garage.js" asp-append-version="true"></script>
|
||||
}
|
||||
@if (Model is not null && Model.Errors.Any())
|
||||
{
|
||||
foreach(string error in Model.Errors)
|
||||
foreach (string error in Model.Errors)
|
||||
{
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
@error
|
||||
@@ -26,30 +25,29 @@
|
||||
<div class="modal fade" id="addVehicleModal" tabindex="-1" role="dialog" aria-labelledby="addVehicleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<form class="form-inline" asp-action="AddVehicle" enctype="multipart/form-data">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addVehicleModalLabel">Add New Vehicle</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<form class="form-inline">
|
||||
<div class="form-group">
|
||||
<label for="inputYear">Year</label>
|
||||
<input asp-for="Year" type="number" id="inputYear" class="form-control">
|
||||
<input type="number" id="inputYear" class="form-control">
|
||||
<label for="inputMake">Make</label>
|
||||
<input asp-for="Make" type="text" id="inputMake" class="form-control">
|
||||
<input type="text" id="inputMake" class="form-control">
|
||||
<label for="inputModel">Model</label>
|
||||
<input asp-for="Model" type="text" id="inputModel" class="form-control">
|
||||
<input type="text" id="inputModel" class="form-control">
|
||||
<label for="inputLicensePlate">License Plate</label>
|
||||
<input asp-for="LicensePlate" type="text" id="inputLicensePlate" class="form-control">
|
||||
<input type="text" id="inputLicensePlate" class="form-control">
|
||||
<label for="inputImage">Upload a picture(optional)</label>
|
||||
<input asp-for="Image" type="file" accept=".png" class="form-control-file" id="inputImage">
|
||||
<input onChange="uploadFileAsync()" type="file" accept=".png" class="form-control-file" id="inputImage">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="hideAddVehicleModal()">Cancel</button>
|
||||
<button type="submit" class="btn btn-primary">Add New Vehicle</button>
|
||||
<button type="button" onclick="addVehicle()" class="btn btn-primary">Add New Vehicle</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,7 +1,10 @@
|
||||
function showAddVehicleModal() {
|
||||
var uploadedFile = "";
|
||||
function showAddVehicleModal() {
|
||||
uploadedFile = "";
|
||||
$('#addVehicleModal').modal('show');
|
||||
}
|
||||
function hideAddVehicleModal() {
|
||||
uploadedFile = "";
|
||||
$('#addVehicleModal').modal('hide');
|
||||
}
|
||||
$(document).ready(function () {
|
||||
@@ -26,4 +29,71 @@ function saveVehicleNote(vehicleId) {
|
||||
//window.location.href = '/Home';
|
||||
}
|
||||
})
|
||||
}
|
||||
function addVehicle() {
|
||||
var vehicleYear = $("#inputYear").val();
|
||||
var vehicleMake = $("#inputMake").val();
|
||||
var vehicleModel = $("#inputModel").val();
|
||||
var vehicleLicensePlate = $("#inputLicensePlate").val();
|
||||
//validate
|
||||
var hasError = false;
|
||||
if (vehicleYear.trim() == '' || parseInt(vehicleYear) < 1900) {
|
||||
hasError = true;
|
||||
$("#inputYear").addClass("is-invalid");
|
||||
} else {
|
||||
$("#inputYear").removeClass("is-invalid");
|
||||
}
|
||||
if (vehicleMake.trim() == '') {
|
||||
hasError = true;
|
||||
$("#inputMake").addClass("is-invalid");
|
||||
} else {
|
||||
$("#inputMake").removeClass("is-invalid");
|
||||
}
|
||||
if (vehicleModel.trim() == '') {
|
||||
hasError = true;
|
||||
$("#inputModel").addClass("is-invalid");
|
||||
} else {
|
||||
$("#inputModel").removeClass("is-invalid");
|
||||
}
|
||||
if (vehicleLicensePlate.trim() == '') {
|
||||
hasError = true;
|
||||
$("#inputLicensePlate").addClass("is-invalid");
|
||||
} else {
|
||||
$("#inputLicensePlate").removeClass("is-invalid");
|
||||
}
|
||||
if (hasError) {
|
||||
return;
|
||||
}
|
||||
$.post('/Home/AddVehicle', {
|
||||
imageLocation: uploadedFile,
|
||||
year: vehicleYear,
|
||||
make: vehicleMake,
|
||||
model: vehicleModel,
|
||||
licensePlate: vehicleLicensePlate
|
||||
}, function (data) {
|
||||
if (data) {
|
||||
successToast("Vehicle added");
|
||||
hideAddVehicleModal();
|
||||
loadGarage();
|
||||
} else {
|
||||
errorToast("An error has occurred, please try again later.");
|
||||
}
|
||||
});
|
||||
}
|
||||
function uploadFileAsync() {
|
||||
let formData = new FormData();
|
||||
formData.append("file", $("#inputImage")[0].files[0]);
|
||||
$.ajax({
|
||||
url: "/Files/HandleFileUpload",
|
||||
data: formData,
|
||||
cache: false,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST',
|
||||
success: function (response) {
|
||||
if (response.trim() != '') {
|
||||
uploadedFile = response;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user