ViewBag.Message not showing ASP.NET MVC c# - c#

I have a view named Index.cshtml and controller named HomeController and I can't seem to show the ViewBag.Message and ViewBag.FileUrl to the view. The code is working I just can't show the ViewBag.message when the file is successfully uploaded.
Here's my code below
Index.cshtml
#{
ViewBag.Title = "Upload a file to S3 Bucket";
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<h3>#ViewBag.FileUrl</h3>
<p>Use this area to browse image and upload to S3 bucket.</p>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.TextBox("file", "", new { type = "file" }) <br />
<input type="submit" value="Upload" />
#ViewBag.FileUrl
#ViewBag.Message
</div>
}
HomeController.cs
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
var s3Client = new AmazonS3Client(accesskey, secretkey, bucketRegion);
var result = "";
var keyName = file.FileName;
var fileTransferUtility = new TransferUtility(s3Client);
try
{
if (file.ContentLength > 0)
{
var filePath = Path.Combine(Server.MapPath("~/App_Data"), Path.GetFileName(file.FileName));
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
BucketName = bucketName,
FilePath = filePath,
StorageClass = S3StorageClass.StandardInfrequentAccess,
PartSize = 6291456, // 6 MB.
Key = keyName,
CannedACL = S3CannedACL.PublicRead
};
fileTransferUtilityRequest.Metadata.Add("param1", "Value1");
fileTransferUtilityRequest.Metadata.Add("param2", "Value2");
fileTransferUtility.Upload(fileTransferUtilityRequest);
fileTransferUtility.Dispose();
}
result = string.Format("http://{0}.s3.amazonaws.com/{1}", bucketName, keyName);
ViewBag.FileUrl = result;
ViewBag.Message = "File Uploaded Successfully!!";
}
catch (AmazonS3Exception amazonS3Exception)
{
ViewBag.Message = "Error occurred: " + amazonS3Exception.Message;
}
return RedirectToAction("Index");
}

You assign ViewBag values, which are lost by the subsequent RedirectToAction().
Found the answer here, with detailed comparison of ViewData, ViewBag, and TempData. In your case, TempData should work.

You are doing redirect the result so that value becomes null, instead of that use Tempdata in where assign a value and get it where you redirect,
catch (AmazonS3Exception amazonS3Exception)
{
Tempdata["Message"]="Error occurred: " + amazonS3Exception.Message;
}
and Index action method, try it like below ,
[HttpGet]
public ActionResult Index()
{
ViewBag.Message= (string)Tempdata["Message"]
return View();
}

Related

Image Slider does not work at random moments

I have created an Image Slider using jQuery, but it doesn't work at random moments. After reloading the page I get the following error:
Uncaught TypeError: Cannot read property 'indexOf' of undefined
at i.fn.init.i.fn.load (jquery?v=eJAcMfrInnLuvmR6YmGFt2ky0cO2ssn2OaxtB6iWFKQ1:1)
at HTMLImageElement.<anonymous> (slider?v=iXGFgGvKoKTyJMnF1faQOZMvYM6od0eK7irNUQ3FiMg1:1)
at Function.each (jquery?v=eJAcMfrInnLuvmR6YmGFt2ky0cO2ssn2OaxtB6iWFKQ1:1)
at i.fn.init.each (jquery?v=eJAcMfrInnLuvmR6YmGFt2ky0cO2ssn2OaxtB6iWFKQ1:1)
at HTMLImageElement.<anonymous> (slider?v=iXGFgGvKoKTyJMnF1faQOZMvYM6od0eK7irNUQ3FiMg1:1)
at Function.each (jquery?v=eJAcMfrInnLuvmR6YmGFt2ky0cO2ssn2OaxtB6iWFKQ1:1)
at i.fn.init.each (jquery?v=eJAcMfrInnLuvmR6YmGFt2ky0cO2ssn2OaxtB6iWFKQ1:1)
at et (slider?v=iXGFgGvKoKTyJMnF1faQOZMvYM6od0eK7irNUQ3FiMg1:1)
at ft (slider?v=iXGFgGvKoKTyJMnF1faQOZMvYM6od0eK7irNUQ3FiMg1:1)
at k (slider?v=iXGFgGvKoKTyJMnF1faQOZMvYM6od0eK7irNUQ3FiMg1:1)
Controller:
public class SliderController : Controller
{
// GET: Slider
public ActionResult Index()
{
using (BasDbContext db = new BasDbContext())
{
return View(db.gallery.ToList());
}
//return View();
}
//Add Images in slider
public ActionResult AddImage()
{
return View();
}
[HttpPost]
public ActionResult AddImage(HttpPostedFileBase ImagePath)
{
if (ImagePath != null)
{
// You can skip this block, because it is only to force the user to upload specific resolution pics
//System.Drawing.Image img = System.Drawing.Image.FromStream(ImagePath.InputStream);
//if ((img.Width != 800) || (img.Height != 356))
//{
// ModelState.AddModelError("", "Image resolution must be 800 x 356 pixels");
// return View();
//}
// Upload your pic
string pic = System.IO.Path.GetFileName(ImagePath.FileName);
string path = System.IO.Path.Combine(Server.MapPath(#"\cdm\Content\images\"), pic);
ImagePath.SaveAs(path);
using (BasDbContext db = new BasDbContext())
{
Gallery gallery = new Gallery { ImagePath = #"\cdm\Content\images\" + pic };
db.gallery.Add(gallery);
db.gallery.Add(gallery).DateAdded = gallery.DateAdded = DateTime.Now;
db.SaveChanges();
}
}
return RedirectToAction("Index");
}
// Delete Multiple Images
public ActionResult DeleteImages()
{
using (BasDbContext db = new BasDbContext())
{
return View(db.gallery.ToList());
}
}
[HttpPost]
public ActionResult DeleteImages(IEnumerable<int> ImagesIDs)
{
using (BasDbContext db = new BasDbContext())
{
try
{
foreach (var id in ImagesIDs)
{
var image = db.gallery.Single(s => s.ID == id);
string imgPath = Server.MapPath(image.ImagePath);
db.gallery.Remove(image);
if (System.IO.File.Exists(imgPath))
System.IO.File.Delete(imgPath);
}
db.SaveChanges();
}
catch
{
TempData["AlertMessage"] = "Something went wrong, try again";
}
}
return RedirectToAction("DeleteImages");
}
}
}
Index:
#model IEnumerable<ConcremoteDeviceManagment.Models.Gallery>
#{
ViewBag.Title = "Index";
//Layout = "~/Views/Shared/_Layout.cshtml";
}
#if (TempData["AlertMessage"] != null)
{
<p class="alert alert-danger" id="successMessage">#TempData["AlertMessage"]</p>
}
<h2>Index</h2>
<p>
<button onclick="location.href='#Url.Action("AddImage", "Slider")';return false; " class="btn btn-primary">Add Image</button>
<button onclick="location.href='#Url.Action("DeleteImages", "Slider")';return false; " class="btn btn-danger">Delete Image</button>
</p>
#Html.Partial("~/Views/Shared/SliderPartial.cshtml", Model)
SliderPartial:
<div class="bxslider">
#foreach (var image in Model)
{
<div><img src="#Url.Content(image.ImagePath)" /></div>
}
</div>
<script>
$(document).ready(function () {
$('.bxslider').bxSlider({
mode: 'fade',
captions: true,
slideWidth: 600
});
});
</script>
I think something is going wrong in SliderPartial.
Controller and Index seems to be fine.
I hope somebody is able to help me out.
More information will be given when needed

Track file download hits/count in ASP.NET MVC5

I have to download file from server directory and keep its download count on Database.
However, I got this to work by the following code.
Razor View
Download
Controller
private AppDbContext db = new AppDbContext();
public ActionResult Download(int id)
{
Item item = db.Items.Find(id);
if (item != null)
{
item.DownloadCount++;
db.SaveChanges();
return File(item.Location, MimeMapping.GetMimeMapping(item.Location), Path.GetFileName(item.Location));
}
return HttpNotFound();
}
This code works perfectly fine except the downloads can't be resumed later.
I know there is other way to download a file using HTML tag like below (which is resumable)...
<a href="/myfile.mp4" download>Download</a>
But, how do I count download on this way?
After hours of browsing I found a solution that works...
Razor View
<a onclick="download(#item.Id)">Download</a>
Javascript
function download(id) {
$.ajax({
url: '#Url.Action("Download", "Home", new {id = "id"})'.replace('id', id),
type: "GET",
success: function (result) {
if (result.success) {
var link = document.createElement('a');
link.href = result.fileLocation;
link.download = '';
link.click();
} else {
alert(result.responseText);
}
},
error: function (errormessage) {
alert(errormessage.responseText);
}
});
}
Controller
public ActionResult Download(int id)
{
Item item = db.Items.Find(id);
if (item != null)
{
item.DownloadCount++;
db.SaveChanges();
string fileLocation = string.Format(
"{0}/{1}",
Request.Url.GetLeftPart(UriPartial.Authority),
item.Location.Replace(#":\\", "/").Replace(#"\", "/")
);
return Json(new { success = true, fileLocation = fileLocation},
JsonRequestBehavior.AllowGet);
}
return Json(new { success = false, responseText = "Bad request." },
JsonRequestBehavior.AllowGet);
}

ASP.NET Razor File Upload

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);
}
}
}

Asp.NET MVC 4 Ajax Request Cancels on Submit

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;"/>

ASP.NET MVC3 Sending Multiple forms from the same page

There are similar posts out there but they do not seem to represent my situation. Apologies in advance if this is a re-post.
I have my view as
#FileUpload.GetHtml(initialNumberOfFiles:1,allowMoreFilesToBeAdded:true,includeFormTag:true, uploadText: "Upload" )
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index","Epub"))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
<input type="submit" value="send" id="pickPartner" hidden="hidden"/>
}
}
<script type="text/javascript">
$(".file-upload-buttons input").click(function () {
$("#pickPartner").click();
});
</script>
my controller is
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, FormCollection collection)
{
int selectedPartner, count =0;
//int selectedPartner = int.Parse(collection["PartnerID"]);
if(!int.TryParse(collection["PartnerID"], out selectedPartner))
{
selectedPartner = 0;
ModelState.AddModelError("", "You must pick a publishing agency");
}
IList<Partner> p = r.ListPartners();
ViewBag.Partners = new SelectList(p.AsEnumerable(), "PartnerID", "Name", selectedPartner);
//make sure files were selected for upload
if (fileUpload != null)
{
for (int i = 0; i < fileUpload.Count(); i++)
{
//make sure every file selected != null
if (fileUpload.ElementAt(i) != null)
{
count++;
var file = fileUpload.ElementAt(i);
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
// need to modify this for saving the files to the server
var path = Path.Combine(Server.MapPath("/App_Data/uploads"), Guid.NewGuid() + "-" + fileName);
file.SaveAs(path);
}
}
}
}
if (count == 0)
{
ModelState.AddModelError("", "You must upload at least one file!");
}
return View();
}
I am using the file upload helper from Microsoft Web Helpers to upload files. The problem I am having is the helper created a form and I have another form I need to submit data from as well on the same page.
I thought I could link the submit buttons so that when you click upload it also sent the other form data but the data is not being sent. Each form works independently of the other with no issue but I need them to work together. Any advice would be appreciated.
Ok I updated the view with
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index","Epub"))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
<input type="submit" value="send" id="pickPartner"/>
}
}
But now the file data does not seem to be getting passed anymore.
-- Update --
I have made the following changes.
The view now looks like
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index", "Epub", new { enctype = "multipart/form-data" }))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
<input type="submit" value="send" id="pickPartner"/>
}
}
and the controller
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, int PartnerID = 0)
//public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, FormCollection collection)
{
int count =0;
IList<Partner> p = r.ListPartners();
ViewBag.Partners = new SelectList(p.AsEnumerable(), "PartnerID", "Name", PartnerID);
//make sure files were selected for upload
if (fileUpload != null)
{
for (int i = 0; i < fileUpload.Count(); i++)
{
//make sure every file selected != null
if (fileUpload.ElementAt(i) != null)
{
count++;
var file = fileUpload.ElementAt(i);
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
// need to modify this for saving the files to the server
var path = Path.Combine(Server.MapPath("/App_Data/uploads"), Guid.NewGuid() + "-" + fileName);
file.SaveAs(path);
}
}
}
}
if (count == 0)
{
ModelState.AddModelError("", "You must upload at least one file!");
}
return View();
}
}
I am trying to figure out how the file data is getting sent over in the post (if it is) so I can save the files.
-- Final Update with Answer --
Well the problem turned out to be two fold.. 1st the issue with #FileUpload and needing to set includeFormTag: false
The other problem I discovered was I needed to make sure in my #Html.BeginForm I included FormMethod.Post This was discovered when the fileUpload count kept coming back as 0. I ran the profiler on firebug and it pointed out that the file data was not actually getting posted. Here is the corrected code below.
my view
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index", "Epub", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
<input type="submit" value="send" id="pickPartner"/>
}
}
my controller
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, int PartnerID = 0)
{
int count =0;
IList<Partner> p = r.ListPartners();
ViewBag.Partners = new SelectList(p.AsEnumerable(), "PartnerID", "Name", PartnerID);
//make sure files were selected for upload
if (fileUpload != null)
{
for (int i = 0; i < fileUpload.Count(); i++)
{
//make sure every file selected != null
if (fileUpload.ElementAt(i) != null)
{
count++;
var file = fileUpload.ElementAt(i);
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
// need to modify this for saving the files to the server
var path = Path.Combine(Server.MapPath("/App_Data/uploads"), Guid.NewGuid() + "-" + fileName);
file.SaveAs(path);
}
}
}
}
if (count == 0)
{
ModelState.AddModelError("", "You must upload at least one file!");
}
return View();
}
Thank you #Jay and #Vasile Bujac for your help with this.
Set IncludeFormTag to false and put it inside your other form using.
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index","Epub"))
{
#FileUpload.GetHtml(initialNumberOfFiles:1,allowMoreFilesToBeAdded:true,includeFormTag:false, uploadText: "Upload" )
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
<input type="submit" value="send" id="pickPartner" hidden="hidden"/>
}
}
Update:
Try changing the signature of your view to this:
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, int PartnerID = 0)
Check the overloads for FileUpload.GetHtml and see if there is a parameter to set the field name for your file uploads. Previously it was just the files being uploaded, now its files and a parameter, so naming becomes more important.
You should use the same form for dropdownlist and file inputs. You can do this by putting the FileUpload helper inside the form, and setting "includeFormTag" parameter to false.
#model IEnumerable<EpubsLibrary.Models.Partner>
#using (Html.BeginForm("Index","Epub")) {
#FileUpload.GetHtml(initialNumberOfFiles:1,allowMoreFilesToBeAdded:true,includeFormTag:false, uploadText: "Upload" )
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
<input type="submit" value="send" id="pickPartner" hidden="hidden"/>
}

Categories

Resources