Using uploadify to auto submit a users files, in my controller method Request.Files["Name"] keeps returning null but request.form isn't null, I can see the file in request.form when I set a breakpoint and debug it. Am I missing something? I'm testing this on mvc2 but i plan on using it on mvc4.
<link href="../../Content/uploadify.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="../../Scripts/jquery.uploadify.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('#file_upload').uploadify({
'swf': '/Content/uploadify.swf',
'uploader': '/Home/UploadFile',
'auto': true
// Your options here
});
});
</script>
</head>
<body>
<%--<% using (Html.BeginForm("UploadFile", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{ %>--%>
<input type="file" name="file_upload" id="file_upload" style="margin-bottom: 0px" />
<%-- <% } %>--%>
Controller Method:
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
var theFile = Request.Files["file_upload"];
return Json("Success", JsonRequestBehavior.AllowGet);
}
If I add a submit button and then submit it it will work though. I need to be auto though without a submit button.
IIRC Uploadify uses fileData as parameter. So:
var theFile = Request.Files["fileData"];
or even better:
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase fileData)
{
// The fileData parameter should normally contain the uploaded file
// so you don't need to be looking for it in Request.Files
return Json("Success", JsonRequestBehavior.AllowGet);
}
Of course if you are not happy with this name you could always customize it using the fileObjName setting.
Related
I've read a lot of the questions on stackoverflow about this, tried some examples and am still stuck why this won't work. So I am asking the community.
MODEL:
public class UploadModel
{
public string PatientID { get; set; }
public DateTime DrawDate { get; set; }
}
Controller:
public class FileManagementController : Controller
{
[HttpGet]
public ActionResult UpLoad()
{
ViewData["message"] = String.Empty;
UploadModel model = new UploadModel
{
PatientID = String.Empty,
DrawDate = DateTime.Now,
};
return View(model);
}
[HttpPost]
public ActionResult Upload(UploadModel model, HttpPostedFileBase MyFile)
{
if (ModelState.IsValid)
{
//Do Validation and Save here
}
UploadModel newmodel = new UploadModel
{
PatientID = model.PatientID,
DrawDate = model.DrawDate,
};
ViewData["message"] = "data submitted";
return View(newmodel);
}
View:
<form action="" method="post" enctype="multipart/form-data" id="MyForm">
#Html.EditorFor(m => m)
<label for="MyDateTime">My Date Time:</label>
<label for="MyFile">File:</label>
<input type="file" name="MyFile" id="MyFile" /><br />
<input id="submit" name="submit" type="submit" value="Save" />
</form>
From there, I have added to the _Layout.cshtml page the following code (which all maps correctly)
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/jquery-ui-1.7.2.custom.css")" rel="stylesheet" type="text/css" />
<script src='#Href("~/Scripts/jquery-1.7.1.js")' type="text/javascript" ></script>
<script src='#Href("~/Scripts/jquery-ui-1.8.1.custom.min.js")' type="text/javascript" ></script>
<script type="text/javascript" src='#Href("~/Scripts/jquery.alphanumeric.pack.js")'></script>
<script type="text/javascript" src='#Href("~/Scripts/jquery.watermark.min.js")'></script>
Then in Views -> Shared I have added an EditorTemplates folder and have created a DateTime.cshtml page that has:
#model DateTime
#Html.TextBox("", Model.ToString("dd/MM/yyyy"),
new { #class = "date" })
<script type="text/javascript" >
$(document).ready(function () {
//set the date picker
var dtp = '#ViewData.TemplateInfo.GetFullHtmlFieldId("")';
dtp = dtp.replace("[", "_");
dtp = dtp.replace("]", "_");
//window.alert($(dtp).attr("value"));
var hid = ($(dtp).attr("type") == "hidden");
if (!hid) {
$(dtp).datepicker({
showOn: 'button', buttonImage: '#Href("~/Content/images/calendar.gif")%>', buttonImageOnly: true
, changeMonth: true, changeYear: true
, dateFormat: 'dd M yy'//, numberOfMonths: 2
});
}
});
</script>
This seems to be the flavor of most of the tutorials on this, but don't seem to work. No icon appears. In Chrome I get the html5 calendar popup but never the jquery one. Any suggestions at all would be greatly appreciated.
The selector looks incorrect to me. You're code:
var dtp = '#ViewData.TemplateInfo.GetFullHtmlFieldId("")';
Would result in a string: 'my_id', but you still need to tell jQuery that string is an ID, using the # symbol like so:
var dtp = '##ViewData.TemplateInfo.GetFullHtmlFieldId("")';
As a side note, do you really want to export that entire Script tag for each rendered DateTime in your model? Seems unnecessary to me, but you may have already thought about this. My recommendation would be to modify your DateTime.cshtml to simply:
#model DateTime
#Html.TextBox("", Model.ToString("dd/MM/yyyy"), new { #class = "date-picker" })
Then somewhere in your page or Layout, something like:
<script type="text/javascript" >
$(function () {
$('.date-picker').datepicker({
showOn: 'button', buttonImage: '#Href("~/Content/images/calendar.gif")%>', buttonImageOnly: true
, changeMonth: true, changeYear: true
, dateFormat: 'dd M yy'//, numberOfMonths: 2
});
});
</script>
That way, just one script is rendered and all your DateTime's are taken care of.
Since I'm a noob I can't post a comment (sorry!), but the only advice I can give is to make sure that the html derived from #Html.EditorFor(m => m) is exactly what you need (this html is different depending on the model). Here's more info about that: http://msdn.microsoft.com/en-us/library/ee402949(v=vs.98).aspx
Also, I noticed in the javascript section you have a %> at the end here: "#Href("~/Content/images/calendar.gif")%>" and it looks like an error.
I cant' seem to work uploadify on ASP.NET MVC3, I searched a lot and the code below seem to work fine, but not for me. When I try and upload it via html uploading method it works, not so much with uploadify. All libraries are included correctly.
<!-- Not working, HTTP ERROR 500 -->
<input id="file" type="file" name="file" />
<script type="text/javascript">
$(document).ready(function () {
$('#file_upload').uploadify({
// I tried to remove "/" at the start, does not help
'uploader': '/Scripts/u/uploadify.swf',
'script': '/home/upload',
'cancelImg': '/Scripts/u/cancel.png',
'folder': '/upload',
'auto': true,
'onError': function (event, ID, fileObj, errorObj) {
alert(errorObj.type + ' Error: ' + errorObj.info);
}
});
});
</script>
<!-- Working fine -->
<form action="home/upload" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" />
</form>
Home Controller Action
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
var fileName = Path.GetFileName(file.FileName); // Object reference not set to an instance of an object. I get this if I try to upload via uploadify
file.SaveAs(Server.MapPath("~/upload/") + fileName);
return Content(fileName);
}
Didn't you debug your code? Didn't you notice that the file action argument is always null when the Upload action is hit? Your action argument is called file, so you need to specify that using the fileDataName option:
'fileDataName' : 'file',
By default uploadify uses Filedata, so if you don't want to specify this name you could also adapt your action argument name to match this:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase fileData)
{
var fileName = Path.GetFileName(fileData.FileName);
fileData.SaveAs(Path.Combine(Server.MapPath("~/upload/"), fileName));
return Content(fileName);
}
Also make sure that the ~/upload folder exists on your server. It doesn't when you create a new ASP.NET MVC application.
Another problem that I would like to point out with your code is that you have hardcoded absolutely all urls in your javascript. That's very bad and chances are that your application won't work when you deploy it in a virtual directory, say for example IIS.
In ASP.NET MVC you should always use url helpers when dealing with urls, just like that:
<script src="#Url.Content("~/Scripts/u/jquery.uploadify.v2.1.4.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/u/swfobject.js")" type="text/javascript"></script>
<input id="file_upload" type="file" name="file" />
<script type="text/javascript">
$(document).ready(function () {
$('#file_upload').uploadify({
'uploader': '#Url.Content("~/Scripts/u/uploadify.swf")',
'script': '#Url.Action("upload", "home")',
'cancelImg': '#Url.Content("~/Scripts/u/cancel.png")',
'folder': '#Url.Content("~/upload")',
'auto': true,
'onError': function (event, ID, fileObj, errorObj) {
alert(errorObj.type + ' Error: ' + errorObj.info);
}
});
});
</script>
Is use
HttpPostedFileBase file = Request.Files[0];
in my controller with Uploadify
I am having an issue where form errors are persisting on the page even after the form is valid.
I have the following setup:
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
</head>
<body>
#RenderBody()
</body>
</html>
index.cshtml:
#model SimpleForm.Models.Name
#{
ViewBag.Title = "Form";
}
<script>
$().ready(function () {
$("#quote_form").submit(function () {
return true;
});
});
</script>
#using (Ajax.BeginForm("RunQuote", "Page", new AjaxOptions { UpdateTargetId = "quoteSummary" }, new { id = "quote_form", onreset = "return confirm('Clear all form data?')" }))
{
<input type="submit" value="Send" />
<fieldset>
<legend>Name </legend>
<dl>
<dt>First</dt>
<dd>#Html.TextAreaFor(m => m.first, new { onblur = "$('#quote_form').submit();" })</dd>
<dt>Last</dt>
<dd>#Html.TextAreaFor(m => m.last, new { onblur = "$('#quote_form').submit();" })</dd>
</dl>
</fieldset>
<div class="qMatrixSubText">
#Html.ValidationSummary()
#{
Html.ValidateFor(m => m.first);
Html.ValidateFor(m => m.last);
}
</div>
<div id="quoteSummary" class="quoteSummary">
</div>
}
FormController.cs
using System;
using System.Web.Mvc;
using SimpleForm.Models;
namespace SimpleForm.Controllers
{
public class FormController : Controller
{
//
// GET: /Form/
public ActionResult Index()
{
return View();
}
public String RunQuote(Name quote)
{
return "Success!";
}
}
}
Name.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace SimpleForm.Models
{
public class Name
{
[Required()]
public string first { get; set; }
public string last { get; set; }
}
}
The form populates fine, I see the error if I don't put anything into first and the form won't submit. After populating something into first I get the ajax call and then it posts "Success" to the div.
However, this is the problem, the error "the first field is required." still remains on the page. It's as if the ajax submit form is going through before the validation gets a chance to clear the error, and then it never gets the chance.
Any way to get the validation to still remove the errors?
The form is not being validated, because your onblur event is short-circuiting the submission process in jquery-unobtrusive-ajax.js.
Instead, change your onblur event for both fields to the following:
$(this).parents('form:first').find(':submit')[0].click();
This will invoke the jquery.unobtrusive-ajax.js script, causing validation to occur prior to the Ajax submission to the server.
UPDATE
When I looked back at your view, I saw that you are calling #Html.ValidateFor() for your properties. This creates HTML markup outside of the div created by #Html.ValidationSummary.
Because this markup is outside of where unobtrusive validation expects it, this markup is never overwritten, and will always remain. Remove the #Html.ValidateFor() lines. If you need to have the validation messages after your initial load, call validate() on document.ready to set your validation messages.
Because I haven't found a proper solution to this problem, I've decided to simply target the validation-summary-errors div and add the class display:none; to the li elements. This hides the validation errors that have otherwise not cleared before submitting the form.
$('#form_errors').children('div.validation-summary-errors').children('ul').children('li').css('display','none')
There has to be a better solution, but I've tried everything and can't figure out why my attempts to force validation don't work.
i am trying to execute a task after uploading a file. After the task is finished i would like to display some info. At the moment i have an Upload action that will fire after clicking the 'Do task' button which is not good. question :I would like to just trigger the 'Sometask' action and not the Uploadaction?
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.BeginForm("Upload","Home",FormMethod.Post,new { enctype = "multipart/form-data" }) %>
<%{ %>
<%=Html.HiddenFor(model=>model.Filepath) %>
<input type="file" id="upload" name="upload" />
<button id="btnUpload">
upload</button>
<%} %>
<button id="btnTask">
Do Task</button>
<script type="text/javascript">
$(document).ready(function (event) {
$('#btnTask').click(function () {
$.post("/Home/Sometask",
{ filePath: $("#Filepath").val() },
function (data) {
alert(data);
});
event.preventDefault;
});
});
</script>
[HttpPost]
public ActionResult Upload()
{
HttpPostedFileBase selectedFile = Request.Files["upload"];
if (selectedFile.ContentLength > 0)
{
string filePath = Path.Combine(HttpContext.Server.MapPath("\\Uploads\\")
, Path.GetFileName(selectedFile.FileName));
selectedFile.SaveAs(filePath);
UploadModel model = new UploadModel();
model.Filepath = filePath;
return View("Index", model);
}
return View("Index");
}
public string Sometask(string Filepath)
{
Thread.Sleep(5000);
return "ready";
}
Is the Upload() method being called? Looking at the code, I would expect the Sometask() to be called but not the Upload() method. The jQuery code is calling .post when the button is clicked and that should eliminate the normal form posting. If Sometask() is not getting called, you many need to add [HttpPost] attribute to the Sometask() method.
Note that for security reasons files cannot be uploaded from Javascript.
i am trying to display a jquery popup after a fileupload action? not sure how to code this?
<%= Html.BeginForm("Upload","Home",FormMethod.Post,new { enctype = "multipart/form-data" }) %>
<%{ %>
<input type="file" id="upload" name="upload" />
<button id="btnUpload">
upload</button>
<%} %>
<script type="text/javascript">
function SayFinished() {
alert('Finished');
}
</script>
[HttpPost]
public ActionResult Upload()
{
HttpPostedFileBase selectedFile = Request.Files["upload"];
if (selectedFile.ContentLength > 0 )
{
//do some processing call jquery script to open popup: SayFinished()
}
return View("Index");
}
The simplest way to do this is to return a view from your controller after the post that has an onload script.
On the new view, put the following javascript:
In the controller set the following after file uploaded
ViewData["FileUploaded"] = "true";
Then in the view set
<% if (!String.IsnullOrEmpty(ViewData["FileUploaded"]) && ViewData["FileUploaded"] == "true") { %>
<script type="text/javascript">
$(document).ready(function() {
SayFinished();
});
function SayFinished() {
alert('Finished');
}
</script>
<%} %>
You can use this plugins to upload file using jQuery, http://pixelcone.com/jquery/ajax-file-upload-script
Sorry for previous feedback with incorrect information.