How to POST file upload using axios to ASP.NET Controller? - asp.net

I render image uploader in html using this function.
which correctly display image in page. How should I post this FileReader to controller?
showCoverImage(e) {
var file = e.target.files[0];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
return;
}
var img = document.getElementById("thumbnail");
img.file = file;
const fileName = document.querySelector('#cover-image .file-name');
fileName.textContent = file.name;
var reader = new FileReader();
reader.onload = (function (aImg) {
return function (e) {
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
I have controller method for upload using IFromFIle. It receives IFromFIle as parameter.
[HttpPost("/upload/coverImage")]
public async Task<IActionResult> uploadEditorImage(IFormFile upload)
{
var fileName = upload.FileName;
var path = Path.Combine(_mainDirectory, "images");
var pathPath = Path.Combine(path, fileName);
int isUpload = 1;
string errorMsg = string.Empty;
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
var stream = new FileStream(pathPath, FileMode.Create);
await upload.CopyToAsync(stream);
await stream.FlushAsync();
return new JsonResult(new {uploaded:1});
}
Upload call using axios. It posts to controller IFromFile as null.
onCoverImageUpload() {
this.loading = true;
const formData = new FormData();
formData.append("file", this.selectedCoverImage);
let config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
axios.post('/upload/coverImage', formData, config)
.then(res => {
console.log(res);
});
}

First, ensure you could get the file by this.selectedCoverImage.
Second, the name is inconsistent. Change the name file in the formData to upload
formData.append("upload", this.selectedCoverImage);

Finally I changed my controller implementation. Now working.
[HttpPost("/upload/coverImage")]
public async Task<IActionResult> uploadEditorImage()
{
var upload = Request.Form.Files[0];
var fileName = upload.FileName;
var path = Path.Combine(_mainDirectory, "images");
var pathPath = Path.Combine(path, fileName);
string errorMsg = string.Empty;
try {
if (!Directory.Exists(path)) {
Directory.CreateDirectory(path);
}
var stream = new FileStream(pathPath, FileMode.Create);
await upload.CopyToAsync(stream);
await stream.FlushAsync();
return new JsonResult(new {uploaded:1});
}

Related

ASP.NET core with MVC folder pathing/mapping FAIL

Whenever I upload a file I want to have it automatically converted into .pdf (I am doing that using NuGet). The thing is the upload scheme is done using relative paths. I do not know what to put into these parentheses:
var wordDocument = appWord.Documents.Open(uploadedFile);
What should I replace uploadedFile with in order to work? I will leave my relative path mapping code below:
public IActionResult Index1()
{
// Get files from the server
var model = new FilesViewModel();
foreach (var item in Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "upload")))
{
model.Files.Add(
new FileDetails { Name = System.IO.Path.GetFileName(item), Path = item });
}
return View(model);
}
[HttpPost]
public IActionResult Index1(IFormFile[] files)
{
// Iterate each files
foreach (var file in files)
{
// Get the file name from the browser
var fileName = System.IO.Path.GetFileName(file.FileName);
// Get file path to be uploaded
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "upload", fileName);
// Check If file with same name exists and delete it
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
// Create a new local file and copy contents of uploaded file
using (var localFile = System.IO.File.OpenWrite(filePath))
using (var uploadedFile = file.OpenReadStream())
{
var appWord = new Application();
if (appWord.Documents != null)
{
//yourDoc is your word document
var wordDocument = appWord.Documents.Open(uploadedFile);
string pdfDocName = "pdfDocument.pdf";
if (wordDocument != null)
{
wordDocument.ExportAsFixedFormat(pdfDocName,
WdExportFormat.wdExportFormatPDF);
wordDocument.Close();
}
appWord.Quit();
}
uploadedFile.CopyTo(localFile);
}
}
ViewBag.Message = "Files are successfully uploaded";
// Get files from the server
var model = new FilesViewModel();
foreach (var item in Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), "upload")))
{
model.Files.Add(
new FileDetails { Name = System.IO.Path.GetFileName(item), Path = item });
}
return View(model);
}
public async Task<IActionResult> Download(string filename)
{
if (filename == null)
return Content("filename is not availble");
var path = Path.Combine(Directory.GetCurrentDirectory(), "upload", filename);
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
private string GetContentType(string path)
{
var types = GetMimeTypes();
var ext = Path.GetExtension(path).ToLowerInvariant();
return types[ext];
}
private Dictionary<string, string> GetMimeTypes()
{
return new Dictionary<string, string>
{
{".txt", "text/plain"},
{".pdf", "application/pdf"},
{".doc", "application/vnd.ms-word"},
{".docx", "application/vnd.ms-word"},
{".xls", "application/vnd.ms-excel"},
{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"},
{".csv", "text/csv"}
};
}

ASP.NET Cloudinary getting response

I have little problem with using Cloudinary, I can upload the images it works fine but I guess i cant get any response from Cloudinary. Suggestion? about required parameters
Handler
public async Task<Photo> Handle(Command request, CancellationToken cancellationToken)
{
var photoUploadResult = _photoAccessor.AddPhoto(request.File);
var photo = new Photo
{
Url = photoUploadResult.Url,
Id = photoUploadResult.PublicId
};
var success = await _context.SaveChangesAsync() > 0;
if (success) return photo;
throw new Exception("Problem saving changes");
}
Accessor
public PhotoUploadResult AddPhoto(IFormFile file)
{
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var stream = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams
{
File = new FileDescription(file.FileName, stream)
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
if (uploadResult.Error != null)
throw new Exception(uploadResult.Error.Message);
return new PhotoUploadResult
{
PublicId = uploadResult.PublicId,
Url = uploadResult.SecureUri.AbsoluteUri
};
}
What do you get in response? Can you try:
string cloud_name = "<Cloud Name>";
string ApiKey = "<Api-Key>";
string ApiSecret = "<Api-Secret>";
Account account = new Account(cloud_name,ApiKey,ApiSecret);
Cloudinary cloudinary = new Cloudinary(account);
cloudinary.Api.Timeout = int.MaxValue;
var ImguploadParams = new ImageUploadParams()
{
File = new FileDescription(#"http://res.cloudinary.com/demo/image/upload/couple.jpg"),
PublicId = "sample",
Invalidate = true,
Overwrite = true
};
var ImguploadResult = cloudinary.Upload(ImguploadParams);
Console.WriteLine(ImguploadResult.SecureUri);

Return a file from asp.net web api

I've been trying to return a file from my web api. Below is my code somehow downloads the file, but the downloaded file is corrupted.
SomeMethod
{
var stream = new MemoryStream();
// processing the stream.
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(response.FileArray.ToArray())
};
result.Content.Headers.ContentDisposition =
new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "CertificationCard.pdf"
};
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
public HttpResponseMessage Download([FromUri] DownloadRequest req) { }

converting a asp.net mvc to a razor page

I have a asp.net web app that calls a controller action with the following code:
$(function () {
$("#barcode").on("change", function (e) {
// get the current value
var barcode = $('#barcode').val();
// if there's no text, ignore the event
if (!barcode) {
return;
}
// clear the textbox
$("#barcode").val("");
// var holdit = $('#textArea1').val();
$('#textArea1').val($('#textArea1').val() +' '+ barcode);
// post the data using AJAX
$.post('#Url.Action("scanned", "receiveScan")?barcode=' + barcode);
});
})
Controller:
[Produces("application/json")]
[Route("api/receiveScan")]
public class receiveScanController : Controller
{
private static readonly HttpClient client = new HttpClient();
public ActionResult scanned(string barcode)
{
var test = barcode;
receiveScanModel newScan = new receiveScanModel();
newScan.Barcode = barcode;
newScan.companyNo = 1;
string jsonScan = JsonConvert.SerializeObject(newScan, Formatting.Indented);
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://notarealservicehere.azurewebsites.net//api/receivescan");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(jsonScan);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
return Ok();
Trying to convert to my first Razor page, everything works with the exception (obviously) of the $.post part...
Where would this go?
It is a asp.net core app with razor pages
Use a handler for example
on your cs file
public IActionResult OnPostBarcode(string barcode)
on your js
var uri = "myPage/?handler=Barcode"
$.post( uri ,{barcode:barcode}, function( data ) {
console.log(data)
});

Get FileStream from form posted file

I have a control on view page. When user selects the file and clicks on submit button this makes ajax call to upload the file on server. Unfortunately my server method accepts file path (like C:/Videos/1.mp4) to upload. This works great with string demoPath in the code below but I'm not sure how to get similar path when user selects in control. Due to sercurity reasons modern browsers not allows exposing paths. How to achieve this?
[HttpPost]
public async Task<JsonResult> Upload(string lectureId, string filepath)
{
for (int i = 0; i < Request.Files.Count; i++)
{
//// This works great
//string demoPath = "C:/Users/abchi/Desktop/BigBuckBunny.mp4";
var file = Request.Files[i];
var fileName = Path.GetFileName(file.FileName);
//var path = Path.Combine(Server.MapPath("~/User/"), fileName);
//file.SaveAs(path);
//await RunUploader(demoPath);
await RunUploader(get_path_from_posted_file_or_request);
}
return Json(new { error = false, message = "Video uploaded." });
}
public async Task RunUploader(string filePath)
{
// :::::::
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
// ::::
}
// ::::::
}
I'm not sure this is expected because I did not quite understand.
Download the file path of the user's computer can not be - https://stackoverflow.com/a/15201258/4599089
but if you want to have access to the FileStream on your server:
File has InputStream and you can use this:
[HttpPost]
public async Task<JsonResult> Upload(string lectureId, string filepath)
{
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/User/"), fileName);
var fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
file.InputStream.CopyTo(fileStream);
fileStream.Close();
await RunUploader(path); //path or stream
}
return Json(new { error = false, message = "Video uploaded." });
}
public async Task RunUploader(string filePath)
{
// :::::::
using (var fileStream = new FileStream(filePath, FileMode.Open))
{
// ::::
}
// ::::::
}
I asked my fellow dev to make necessary changes in public async Task RunUploader(string filePath) parameters. Said code was part of YouTube .NET samples for console apps. Now we are developing for web, in this case we can't pass full path. So they made following changes:
[HttpPost]
public async Task<JsonResult> Upload(string lectureId)
{
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
Stream fileStream = file.InputStream;
await Run(fileStream);
}
return Json(new { error = false, message = "Video uploaded." });
}
public async Task Run(Stream fileStream)
{
// ::::::::::
using (fileStream)
{
// ::::::
}
// ::::::::::
}
Now with this change everything started working.

Resources