Issue Is with Ajax Request Cancel
After i call the ProcessMessage from form submit i am having issue
Issue with submitting your page is canceling my ajax request, so I am getting error..
Please help me on this
View
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "formUpload", enctype = "multipart/form-data" }))
{
<div>
<b>Upload File</b>
<input type="file" name="file" />
<input type="submit" value="Upload File" name="btnUpload" onclick="progressStatus();"/><br />
</div>
<div>
#ViewBag.Message
</div>
<div style="width: 30%; margin: 0 auto;">
<div id="progressbar" style="width: 300px; height: 15px"></div>
<br/>
</div>
}
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
function progressStatus() {
var oReq = new XMLHttpRequest();
oReq.open("get", "/Home/ProcessMessage", true);
oReq.send();
setInterval(showResult, 1000);
function showResult() {
var result = "";
if (result !== oReq.responseText) {
result = oReq.responseText;
debugger;
$("#progressbar").html(result);
}
}
return false;
}
</script>
Controller
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file != null)
{
var fname = Path.GetFileName(file.FileName);
var exis = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/Storage/uploads"), fname);
if (System.IO.File.Exists(exis))
{
ViewData["Message"] = "The file " + fname + " has already exists";
}
else
{
try
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var folderPath = Server.MapPath("~/Storage/uploads");
fname = fileName;
var path = Path.Combine(folderPath, fileName);
var filebytes = new byte[file.ContentLength];
if (!Directory.Exists(folderPath))
Directory.CreateDirectory(folderPath);
file.SaveAs(path);
}
ViewData["Message"] = "The file " + fname + " has uploaded successully";
}
catch (Exception e)
{
ViewData["Message"] = "The file " + fname + " Could not upload";
ViewData["Message"] = e.Message;
}
}
}
else
ViewData["Message"] = "Please choose file";
return View();
}
public class ProgressiveResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
for (int i = 0; i < 20; i++)
{
context.HttpContext.Response.Write(i.ToString());
Thread.Sleep(2000);
context.HttpContext.Response.Flush();
}
context.HttpContext.Response.End();
}
}
and this is an action that returns this result:
public ActionResult ProcessMessage()
{
return new ProgressiveResult();
}
You have to return false in click event handler to cancel submitting the form:
<input type="submit" value="Upload File" name="btnUpload" onclick="progressStatus(); return false;"/>
Related
I'm trying to achieve to pass a file from the client to my controller in mvc in order to transform the file to a ByteArray, I was thinking that was a simple task but it actually giving me some hard times.. so far I'm able to hit correctly my controller:
HTML
<form method="post" id="myform" enctype="multipart/form-data"
asp-controller="UploadFiles" asp-action="Index">
<div class="form-group">
<div class="col-md-10">
<p>Seleziona un file ORI ed un file MOD.</p>
<label for="fileOri">Seleziona ORI</label>
<input id="fileOri" type="file" name="fileOri" multiple />
<p></p>
<label for="fileMod">Seleziona MOD</label>
<input id="fileMod" type="file" name="fileMod" multiple />
<p></p>
<input id="check" name="checkBoxCorreggi" type="checkbox" />
<label for="check">Correggi Checksum</label>
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<p></p>
<input type="submit" id="VerificaChecksum" value="Verifica Checksum" />
<!--value= "Verifica Checksum-->
<p></p>
</div>
</div>
</form>
JavaScript
$(function () {
$('#VerificaChecksum').click(function () {
var file = document.getElementById('fileOri'),
formData = new FormData();
if (file.files.length > 0) {
for (var i = 0; i < file.files.length; i++) {
formData.append('file' + i, file.files[i]);
}
}
$.ajax({
url: '#Url.Action("UploadFiles", "UploadFiles")',
type: 'POST',
data: formData,
dataType: "json",
cache: false,
contentType: false,
processData: false
});
});
});
MVC CONTROLLER
public class UploadFilesController : Controller
{
int result = 0;
int count = 0;
byte[] fileOri;
byte[] fileMod;
[DllImport(#"c:\Windows\System32\inetsrv\dll194.dll", EntryPoint = "get_cks_XXX")]
public static extern int get_cks_XXX(byte[] pBuf_mod, byte[] pBuf_ori, int len_Buf, bool flag);
private readonly IHostingEnvironment _hostingEnvironment;
public UploadFilesController(IHostingEnvironment hostingEnvironment)
{
this._hostingEnvironment = hostingEnvironment;
}
#region snippet1
[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(IList<IFormFile> files, string[] checkBoxCorreggi)
{
long size = files.Sum(f => f.Length);
// full path to file in temp location
var filePath = Path.GetTempFileName();
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
using (var stream = new MemoryStream())
{
await formFile.CopyToAsync(stream);
if (count == 0)
{
fileOri = stream.ToArray();
}
else
{
fileMod = stream.ToArray();
}
}
}
count++;
}
if (checkBoxCorreggi.Length == 1)
{
result = get_cks_XXX(fileMod, fileOri, fileOri.Length, true);
return File(fileMod, "application/force-download", "modCorretto.mod");
}
else
{
result = get_cks_XXX(fileMod, fileOri, fileOri.Length, false);
return Ok(new { count = files.Count, size, filePath });
}
}
#endregion
}
As I said before I'm currently able to hit my controller, but the problem is that the IList<IFormFile> files is actually null, where I'm getting wrong?
I hope this will work.
I have just only one file to send so i am doing this is Asp.Net Core
You can add your conditions as well like Files.Count or something you want.
Here is my code to save file
[HttpPost]
public async Task<JsonResult> SaveRegistration(string registration)
{
var message = "";
var status = "";
try
{
var path = Path.Combine(_hostingEnvironment.WebRootPath, "Files\\Images");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
path += "\\";
if (!string.IsNullOrEmpty(registration))
{
var reg = new Registration();
reg.Name = registration;
var file = Request.Form.Files[0];
if (file != null)
{
var fileName = file.FileName;
if (System.IO.File.Exists(path + fileName))
{
fileName = $"{DateTime.Now.ToString("ddMMyyyyHHmmssfff")}-{fileName}";
}
using (var fileStream = new FileStream(path + fileName, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
reg.Picture = fileName;
}
_context.Registration.Add(reg);
await _context.SaveChangesAsync();
message = "Data is not saved";
status = "200";
}
}
catch (Exception ex)
{
message = ex.Message;
status = "500";
}
return Json(new
{
Message = message,
Status = status
});
}
I use the following code to upload files using a webAPI, the file upload part works fine but how can I access all additional input values and hidden input values from the post?
[HttpPost]
public async Task<object> UploadFile()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
}
var streamProvider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data/Temp/"));
try
{
await Request.Content.ReadAsMultipartAsync(streamProvider);
foreach (MultipartFileData fileData in streamProvider.FileData)
{
var fileName = "";
if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
{
fileName = Guid.NewGuid().ToString();
}
fileName = fileData.Headers.ContentDisposition.FileName;
if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(#"/") || fileName.Contains(#"\"))
{
fileName = Path.GetFileName(fileName);
}
File.Move(fileData.LocalFileName, Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), Path.GetDirectoryName(fileName) + Guid.NewGuid() + Path.GetExtension(fileName)));
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
And here is the form I am using for posting the file.
<form name="form1" method="post" enctype="multipart/form-data" action="api/upload">
<div>
<label for="caption">Image Caption</label>
<input name="caption" type="text" />
</div>
<div>
<input type="hidden" value="secretvalue"/>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
I'm following this example on the MS website for File Uploads using Razor and C#.
If I have more than one File upload buttons, how would the C# code know which button the uploaded file is from? Based on the button the file was uploaded from, I will be saving files to specific folders.
https://learn.microsoft.com/en-us/aspnet/web-pages/overview/data/working-with-files
#using Microsoft.Web.Helpers;
#{
var fileName = "";
if (IsPost) {
var fileSavePath = "";
var uploadedFile = Request.Files[0];
fileName = Path.GetFileName(uploadedFile.FileName);
fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" +
fileName);
uploadedFile.SaveAs(fileSavePath);
}
}
<!DOCTYPE html>
<html>
<head>
<title>FileUpload - Single-File Example</title>
</head>
<body>
<h1>FileUpload - Single-File Example</h1>
#FileUpload.GetHtml(
initialNumberOfFiles:1,
allowMoreFilesToBeAdded:false,
includeFormTag:true,
uploadText:"Upload")
#if (IsPost) {
<span>File uploaded!</span><br/>
}
</body>
</html>
The way to do this is to name the buttons the same, but give them different values. You can then do a case statement and direct the logic based on the value.
Razor
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="FirstUpload" />
<input type="submit" name="submitID" id="submitID" value="Upload1" />
<input type="file" name="SecondUpload" />
<input type="submit" name="submitID" id="submitID" value="Upload2" />
}
Controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
string btn = Request.Params["submitID"];
switch (btn)
{
case "Upload1":
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
}
break;
case "Upload2":
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
}
break;
}
return View();
}
I had a similar problem and ended up with following code:
Razor
//BeginForm and other staff
#foreach (var d in Model.Types)
{
<input type="file" name="doc:#d.Id:upload" />//#d.Id is the key point
<button formenctype="multipart/form-data"
type="submit" formaction="/MyController/uploaddoc"
name="typeid" formmethod="post" value="#d.Id">//this way I send Id to controller
Upload
</button>
}
MyController
[HttpPost]
[ValidateAntiForgeryToken]
[Route("mycontroller/uploaddoc")]//same as formaction
public async Task<ActionResult> UploadDoc(FormCollection data, int typeid)
{
//restore inpput name
var fl = Request.Files["doc:" + typeid.ToString() + ":upload"];
if (fl != null && fl.ContentLength > 0)
{
var path = Server.MapPath("~/app_data/docs");
var fn = Guid.NewGuid().ToString();//random name
using (FileStream fs = System.IO.File.Create(Path.Combine(path, fn)))
{
await fl.InputStream.CopyToAsync(fs);
}
}
}
Hi to all of you I am facing a problem on uploading a file and saving it into a folder here is my view
<div class="admin-empty-dashboard">
#using (Html.BeginForm("UploadResumes", "Employee", new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="icon">
<i class="ion-ios-book-outline"></i>
</div>
<h4>Welcome #Model.FullName!</h4>
<p>#ViewBag.Error</p>
<div class="form-group bootstrap-fileinput-style-01">
<label>Upload Resume</label>
<input type="file" name="file" required="required" class="btn btn-primary" style="margin-left:265px" accept="application/msword,text/plain, application/pdf">
<span class="font12 font-italic">** File must not bigger than 2MB</span>
</div>
<input type="submit" name="name" class="btn btn-primary" value="UploadResumes" />
}
</div>
and here is my controllers action problem is that it HttpPostedFileBase object value is always null and i ran Request.Files.Count it's also giving me zero where is problem?
public ActionResult UploadResumes(HttpPostedFileBase file)
{
if (Session["UserID"] != null && Session["UserName"] != null && Session["EmployeeID"] != null)
{
int id = Convert.ToInt32(Session["EmployeeID"]);
string[] allowedExtenssions = new string[] { ".pdf", ".doc", ".docx" };
string cvPath = "~/cvs/Employee_cvs/";
if (!Directory.Exists(Server.MapPath(cvPath)))
Directory.CreateDirectory(Server.MapPath(cvPath));
MyDbContext db=new MyDbContext();
tblEmployee employee = (from s in db.tblEmployees where s.UserId == id select s).FirstOrDefault();
// HttpPostedFileBase cv = Request.Files["CV"];
if (file != null)
{
if (file.ContentLength > 0)
{
string ext = Path.GetExtension(file.FileName);
if (allowedExtenssions.Contains(ext.ToLower()))
{
string fileName = DateTime.Now.Ticks + ext;
string filePath = cvPath + fileName;
string serverPath = Server.MapPath(filePath);
file.SaveAs(serverPath);
employee.cvUrl = filePath;
}
}
ViewBag.Error = "Some Error Occured";
}
return RedirectToAction("Dashboard");
}
else
{
return RedirectToAction("Login", "User");
}
}
Update like below and check
#using (Html.BeginForm("UploadResumes", "Employee",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
Also
[HttpPost]
public ActionResult UploadResumes(HttpPostedFileBase file)
{
}
Try changing your parameters on your controller to
public ActionResult UploadResumes(Model yourModel, HttpHostedFileBase file)
In most of my controllers that require a file for upload, are usually array based. Make you function parameters an array like this:
public ActionResult UploadResumes(HttpPostedFileBase[] files){
}
My Html code:
<div class="col-md-6">
<img ngf-src="!picFile.$error && picFile" style="height: 150px; width: 200px;">
<input type="file" ngf-select ng-model="picFile" name="file"
accept="image/*" ngf-max-size="2MB"><b>Picture</b><br />
</div>
<div class="col-md-6">
<img ngf-src="!sigFile.$error && sigFile" style="height: 150px; width: 200px;">
<input type="file" ngf-select ng-model="sigFile" name="file"
accept="image/*" ngf-max-size="2MB"><b>Signature</b><br />
</div>
And My angular code
$scope.SaveNewJoinHolder = function (picFile, sigFile) {
if (investor_validity == 1) {
if ($scope.newJoinHolderForm.$valid) {
if (typeof $scope.newJoinHolder.DOB == undefined) {
$scope.newJoinHolder.DOB = null;
}
else {
var datefilter = $filter('date');
$scope.newJoinHolder.DOB = datefilter($scope.newJoinHolder.DOB, 'dd/MM/yyyy');
$scope.newJoinHolder.birth_date = dateconfigservice.FullDateUKtoDateKey($scope.newJoinHolder.DOB);
}
Upload.upload(
{
url: '/InvestorManagement/JoinHolder/SaveNewJoinHolder',
method: 'POST',
fields: $scope.newJoinHolder,
file: { picFile: picFile, sigFile: sigFile },
async: true
})
.success(function () {
toastr.success('Submitted Successfully');
}).error(function () {
toastr.success('Failed');
});
}
}
};
I debugged the code and I got both of the file while debugging. But it is not calling my C# method
public JsonResult SaveNewJoinHolder(tblJoinHolder joinHolder, HttpPostedFileBase picFile, HttpPostedFileBase sigFile)
{
joinHolderFactory = new JoinHolderFactory();
try
{
joinHolder.membership_id = SessionManger.BrokerOfLoggedInUser(Session).membership_id;
joinHolder.changed_user_id = User.Identity.GetUserId();
joinHolder.changed_date = DateTime.Now;
joinHolder.is_dirty = 1;
byte[] image = new byte[picFile.ContentLength];
picFile.InputStream.Read(image, 0, picFile.ContentLength);
joinHolder.photo = image;
byte[] signature = new byte[sigFile.ContentLength];
sigFile.InputStream.Read(image, 0, sigFile.ContentLength);
joinHolder.signature = signature;
joinHolderFactory.Add(joinHolder);
joinHolderFactory.Save();
return Json(new { data = "Successfully Saved Data", success = true });
}
catch (Exception ex)
{
return Json(new { data = ex.Message, success = false });
}
}
What is the problem here?
If I try to upload single image it is working.
Before version 7.2.0 you couldn't specify a map as file option so you had to do
Upload.upload(
{
url: '/InvestorManagement/JoinHolder/SaveNewJoinHolder',
method: 'POST',
fields: $scope.newJoinHolder,
file: [picFile, sigFile],
fileFormDataName: ['picfile', 'sigFile'],
})
But since version 7.2.0 your original code should work.
You can verify the network tab of your browser to make sure that the file form data is being sent to the server.