How to show succes alert on file upload? - c#

I'm currently working on a project where I upload files with the following code:
<div class="row">
<div class="col-lg-2 d-flex align-items-stretch">
#using (Html.BeginForm("ImportOther", "Mapper", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<p>
<label class="btn btn-block btn-primary">
Other JSON / XML <input type="file" name="jsonFileOther" onchange="this.form.submit()" style="display: none;">
</label>
</p>
}
</div>
</div>
How can I show a succes alert when file has been uploaded? I've used alerts in javascript so far. Hope anyone has some suggestions.
Thanks in advance!

After you have submitted your form to the Controller, based upon your upload result, you can set a message using ViewBag.
In your Controller:
if(fileUpload == true)
{
ViewBag.UploadMessage = "File Successfully Uploaded";
}
else
{
ViewBag.UploadMessage = "Could Not Upload File";
}
You can use the ViewBag like this in your View:
#if(ViewBag.UploadMessage != null)
{
<script>
$(document).ready(function(){
alert('#ViewBag.UploadMessage ');
});
</script>
}
Note: Instead of using return RedirectToAction(), use return View() to preserve your ViewBag variable.

Related

How do I pass the images while passing a model in Dropzone.js ASP.NET MVC C#

To start, I'm making a product edit page. When you edit a product, it's all the fields from a database going through a model. I'm using Dropzone.js to upload multiple images for the product with previews and an ability to remove before submitting the edits the user has made. A user can drag and drop or select multiple images. This works fine, the problem is when trying to submit it, the images are not passed to the controller for some reason where as the model is. I made a page dedicated to the uploading and it works great, but when I attempt to pass a model and the images, it passes only the Model and the images are null.
Controller
[HttpPost]
public ActionResult ProductEdit(IEnumerable<HttpPostedFileBase> files, TWebProduct tbl, HttpPostedFileBase file)
{
// A bunch of stuff that doesn't matter because it returns as null before it hits this.
}
This is the top of the ProductEdit.cshtml as you can see the model and using tag.
Top of the ProductEdit.cshtml
#model EcommerceAirmotion.DAL.TWebProduct
#{
ViewBag.Title = "ProductEdit";
Layout = "~/Views/Shared/_AdminLayoutPage.cshtml";
}
<h2>Product Details</h2>
<script src="~/Scripts/jquery-3.6.0.min.js"></script>
#using (Html.BeginForm("ProductEdit", "Admin", FormMethod.Post, new { #name = "myDropzone", id = "myDropzone", enctype = "multipart/form-data" }))
{
#* a bunch of other stuff *#
<div class="form-group">
<h5>Images</h5>
<div class="col-md-10">
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Image Prev</th>
<th>Name</th>
</tr>
</thead>
<tbody>
#foreach (var img in Model.TWebImages)
{
<tr>
<td><img src="~/ProductImages/#img.varImage" class="img-fluid" width="150" height="150" /></td>
<td>#img.varImage</td>
</tr>
}
</tbody>
</table>
<h5>Upload Images</h5>
<div>
<div id="previews" class="dz-default dz-message box__input dropzone border">
<br/>
<div style="text-align:center">
<i class="fa fa-cloud-upload" style="font-size:23px;position:relative;top:4px;"></i> <span style="margin-left:20px">Drop files to attach or browse</span>
</div>
<br />
</div>
<div id="previewFiles" class=""></div>
</div>
</div>
</div>
#* a bunch of other stuff *#
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
}
#section scripts{
<script>
$(document).ready(function () {
Dropzone.autoDiscover = false;
$('#myDropzone').dropzone({
//parameter name value
paramName: "files",
//clickable div id
clickable: '#previews',
//preview files container Id
previewsContainer: "#previewFiles",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
//url:"../ProductImages/", // url here to save file
maxFilesize: 100,//max file size in MB,
addRemoveLinks: true,
dictResponseError: 'Server not Configured',
//acceptedFiles: ".png,.jpg,.gif,.bmp,.jpeg,.pdf",// use this to restrict file type
acceptedFiles: ".png,.jpg,.gif,.bmp,.jpeg",// use this to restrict file type
init: function () {
var self = this;
// config
self.options.addRemoveLinks = true;
self.options.dictRemoveFile = "Delete";
//New file added
self.on("addedfile", function (file) {
console.log('new file added ', file);
$('.dz-success-mark').hide();
$('.dz-error-mark').hide();
});
// Send file starts
self.on("sending", function (file, xhr, formData) {
console.log('upload started', file);
$('.meter').show();
});
// File upload Progress
self.on("totaluploadprogress", function (progress) {
console.log("progress ", progress);
$('.roller').width(progress + '%');
});
self.on("queuecomplete", function (progress) {
$('.meter').delay(999).slideUp(999);
});
// On removing file
self.on("removedfile", function (file) {
console.log(file);
});
$('#Submit').on("click", function (e) {
e.preventDefault();
e.stopPropagation();
// Validate form here if needed
if (self.getQueuedFiles().length > 0) {
self.processQueue();
} else {
self.uploadFiles([]);
$('#myDropzone').submit();
}
});
self.on("successmultiple", function (files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
$(".alert").alert('close');
});
}
});
})
</script>
}
Also on the edit page html
This is the ProductEdit.cshtml part where the drop and drag go
This is the script for the dropzone on the product edit page
Script on the ProductEdit.cshtml
These are the errors from the dev tools from chrome
DevTools Error messages
I have little to no experience with javascript, very small experience (like 40 hours of experience) in MVC, but am decently well versed in C#
Please help me find what I'm doing wrong.
Let me know if I need to clarify anything better.
I found the answer, the submit button didn't have the name attribute. This was not calling the javascript to actually save the images.
old submit button:
<input type="submit" value="Save" class="btn btn-primary" />
New submit button:
<input type="submit" value="Submit" id="Submit" name="Submit" class="btn btn-primary" />

Upload File in MVC gives null Exception [duplicate]

I want to upload multiple files including Word Documents, Pdf and Images.
I need to use a single input for files because we don't know how many files will be uploaded.
My code is this but I have problem that I can't send files to server side.
Controller Code :
public ActionResult Create([Bind(Include = "Id,Content")] Message message, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
// Object save logic
SaveFiles(message,files);
return RedirectToAction("Index");
}
return View(message);
}
Part of view code :
<form name="registration" action="">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label for="Content" >Content:</label>
<textarea class="form-control compose_content" rows="5" id="Content" name="content"></textarea>
<div class="fileupload">
Attachment :
<input id="files" name="files" type="file" multiple />
</div>
</div>
<button type="submit" class="btn btn-default compose_btn" >Send Message</button>
</form>
I don't have problem with saving files and saving the object.
only problem :
files list is null.
I order to upload files, your form needs to include the enctype= multipart/form-data attribute.
<form name="registration" action="" enctype= "multipart/form-data">
or better
#using (Html.BeginForm(actionName, controllerName, FormMethod.Post, new { enctype= "multipart/form-data" }))
and I strongly recommend you pass a model to the view and use the strongly typed HtmlHelper methods to create your html for the properties of your model.

Making action in controller void

I have this kind of problem: In a view I have one button upload which uploads an image and stores it to some folder. Is there a way to call action upload, but not to return a view? Just to save that content, and then I have another button next which will redirect me to a new view. I tried with return type void, but it sends me to blank page.
This are form buttons for upload and next
#using (Html.BeginForm("Upload", "Account", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.Picture, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<span class="btn btn-primary btn-file">
Choose <input type="file" name="file" />
</span>
<input type="submit" value="Upload" name="buttonName" class="btn btn-primary"/>
</div>
</div>
}
#using (Html.BeginForm("Next", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="Next" name="buttonName" class="btn btn-default" />
</div>
</div>
}
This is action:
public void Upload(HttpPostedFileBase file, string btnSubmit)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
file.SaveAs(path);
}
}
You can use the Content() method to return ContentResult ContentResult by default returns a text/plain as its contentType.
public ActionResult Upload(HttpPostedFileBase file, string btnSubmit)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
file.SaveAs(path);
}
return Content("Success");
}
You could return an EmptyResult.
MVC wants you to use EmptyResult when the action is specifically
intended to return nothing. Unlike all of the previous ActionResults
though, EmptyResult doesn't have a helper. Additionally, if an action
returns null, MVC will detect that and make it return an EmptyResult.
Ok, I searched about this and I think that i need some ajax without refreshing page. I found this File upload using MVC 4 with Ajax. I'll try it to see if this works.
The correct solutions are to use either:
return new HttpStatusCodeResult(HttpStatusCode.OK);
to indicate the upload was received and all processing has completed.
return new HttpStatusCodeResult(HttpStatusCode.Accepted);
to indicate the upload was received and further processing will continue.

HTML.Partial() is not working when displaying it?

In Asp.net mvc 5. we have a login page which implements HTML.BeginForm() to post data to controller , if the username and password are incorrect, we are sending error back to the front end using partial views. Everything work fine, In case of error only error message is displayed on the screen and nothing else.
Controller
[HttpPost]
public ActionResult SingleSSOMPLogin(SSoStateModel model)
{
//Check the Code with SP providers and Authorization server.
if(model.SAMLAssertion.validMPData)
{
return RedirectToAction("SSOServiceMP" , "SAML");
}else
{
//Error message processed.
model.errorMessage = SSOState.SAMLAssertion.errorMessage;
return PartialView("_LoginError" , model);
}
}
The view contain the following Code
<div class="peripheral">
<div class="panel panel-default panel-peripheral">
#{Html.Partial("_LoginError", Model);}
<div class="panel-heading clearfix">Please Log In</div>
<div class="panel-body">
<div class="brand-logo eop-logo">
<script type="text/javascript">
function changeImage() {
document.getElementById("Logo").src = '#Url.Content("~/Content/images/TopLogo.gif")';
}
</script>
<img id="Logo" width="200" src='#Url.Content("~/Content/images/TopLogo.gif")' onerror="changeImage()" />
#{ Html.EnableClientValidation(true);}
<!--Ajax call to Controller-->
#using (Html.BeginForm("SingleSSOMPLogin", "Accounts"))
{
#Html.ValidationSummary(true);
<div id="group-email" class="form-group col-md-12 ">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control", placeholder = "Please enter your Email address" })
#Html.ValidationMessageFor(m => m.Email)
</div>
<div id="group-password" class="form-group col-md-12">
#Html.PasswordFor(m => m.Password, new { #class = "form-control", placeholder = "Please enter your password" })
#Html.ValidationMessageFor(m => m.Password)
</div>
<div class="form-group">
<div class="col-md-12">
<button type="submit" class="btn btn-primary pull-left">Login</button>
<a id="forgot" href='#Url.Action("ForgotPassword","Accounts")' class="btn btn-link btn-sm pull-right">Forgot your password?</a>
</div>
</div>
}
</div>
</div>
</div>
</div>
Partial View
#{
Layout = null;
}
#if (Model.Result!= null)
{
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<strong>#Model.Result.errorMessage</strong>
</div>
}
When Error occur, I get redirect to same view again with all query parameter gone and display only error message.
How to solve following issue?
The partial view will return only the fragment you defined.
So when called from a "complete" view with
#{Html.Partial("_LoginError", Model);}
it will generate the corresponding part of the view.
In your situation what is most common is to add a model error and return the complete view (that must have a ValidationSummary section):
[HttpPost]
public ActionResult SingleSSOMPLogin(SSoStateModel model)
{
//Check the Code with SP providers and Authorization server.
if(model.SAMLAssertion.validMPData)
{
return RedirectToAction("SSOServiceMP" , "SAML");
}else
{
//Error message processed.
ModelState.AddModelError("error", SSOState.SAMLAssertion.errorMessage);
return View(model);
}
}
If you want to use the partial view you have to call it from an javacript ajax call and insert the response in your page. With jQuery it is something more or less like:
$.ajax({ url: <partial view url>,
type: 'GET',
success: function (result) {
$(updateSelector).hide().html(result).effect("fade", "fast");
}
});

Having two forms in ASP.NET MVC 4 and posting one of them with ajax

I'm developing an ASP.NET MVC 4 web application. I'm a beginner in web application. My problem is with file upload and ajax. I have two forms. One of the is for getting the data from user such as name, family and so more. The other one is to upload image. I want the user be able to upload the image before submitting the registration and also see the uploaded image in an <img> tag. Here is my code:
View
#using (Html.BeginForm("Register", "Customer", FormMethod.Post))
{
<fieldset>
<div class="control-group">
<label class="control-label">Name</label>
<div class="controls">
#Html.TextBoxFor(model => model.Name)
</div>
</div>
<div class="control-group">
<label class="control-label">Family</label>
<div class="controls">
#Html.TextBoxFor(model => model.Family)
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" value="Submit" class="btn btn-info"/>
</div>
</div>
</fieldset>
}
<img src="" class="img"/>
#using (Html.BeginForm("UploadImage", "Customer", FormMethod.Post, new { d="ImageUploadForm", #enctype = "multipart/form-data" }))
{
<input type="file" name="imgfile" class="imgfile"/>
<input type="submit" value="Upload" class="btnUpload btn btn-info" />
}
Action In Controller
[HttpPost]
public string UploadImage(HttpPostedFileBase imgfile)
{
string filePath = "";
if (imgfile != null && imgfile.ContentLength > 0)
{
filePath = Path.Combine(Server.MapPath("~/Customer/"), imgfile.FileName);
imgfile.SaveAs(filePath);
}
return "~/Customer/" + imgfile.FileName;
}
Javascript
$('#ImageUploadForm').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('.img').attr('src', result);
}
})
return false;
}
});
Now the problem is that when I select a file and hit the Upload button, the UploadImage() action is called and file is uploaded, but the success event of ajax is not called and it redirects me to another page called localhost/Customer/UplaodImage it's content is just the file path that UploadImage had returned. Is it ever possible to do this? Or I cant post a form data using ajax and not redirecting to another page? Any help is appreciated.
As I know, you cannot post a file through regular AJAX. Use some helper libraries: FileUploader, etc...
UPDATE:
By Adeel at this answer:
With XHR2, File upload through AJAX is supported. E.g. through
FormData object, but unfortunately it is not supported by all/old
browsers.

Categories

Resources