Uploading files with MVC 3 ajax style - ajax

Maybe it's just me but I'm trying to use a jQuery dialog to capture a file the user wants to upload. It must be supported by IE9. IE9 doesn't support the FormData object which is used in many examples and 3rd party tools I have came across. So in order to make my request not refresh the whole page I have to put my upload into an iFrame? Really? I know I can get some flash uploader but flash isn't supported on our site so that's out of the question right now.
Please.. please someone tell me I'm doing this wrong and there's an easier way because I can't seem to find it.. not one that will work on IE9 at least.
Form
<form action="/ControllerName/ActionName" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" name="submit" value="Submit" />
</form>
Then into an iFrame like this
<iframe src="myUrl"></iframe>

View:
#using (Html.BeginForm("FileUpload","Message",FormMethod.Post,new { enctype="multipart/form-data"})) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Message</legend>
//your html here
<input type="file" name="files"/>
</fieldset>
Controller:
[HttpPost]
public ActionResult FileUpload(FormCollection values, IEnumerable<HttpPostedFileBase> files)
{
//do what you want with form values then for files
foreach (var file in files)
{
if (file.ContentLength > 0)
{
byte[] fileData = new byte[file.ContentLength];
file.InputStream.Read(fileData, 0, file.ContentLength);
//do what you want with fileData
}
}
}
I provide multiple files upload so i use
IEnumerable<HttpPostedFileBase> files
if you want only a single file then use only
HttpPostedFileBase file
and in your view change input type to
<input type="file" name="file"/>
Simple as that.
Regards
EDITED:
Take a look at more good examples:
http://www.strathweb.com/2012/04/html5-drag-and-drop-asynchronous-multi-file-upload-with-asp-net-webapi/
http://css.dzone.com/articles/implementing-html5-drag-drop
Regards

Related

send multipart form with ajax - send file and text

i need to send some data and an image file with ajax .
i know that must use multipart form and formdata but i don't know how - i googled it and i found some way for send file, but i need to send whole form.
this is my html form
<form id="formData" enctype="multipart/form-data">
<input type="file" id="uploader" name="image" accept="image/jpg, image/jpeg, image/png, image/bmp, image/raw"/>
<input type="hidden" name="action" id="action" value="receiver"/>
<input type="hidden" name="route" id="route" value="image"/>
</form>
thanks.
Hope something like this might do it for you mate... :)
html
//Include this script in head
<script src="http://malsup.github.com/jquery.form.js"></script>
The jQuery Form Plugin allows you to easily and unobtrusively upgrade HTML forms to use AJAX. The main methods, ajaxForm and ajaxSubmit, gather information from the form element to determine how to manage the submit process. Both of these methods support numerous options which allows you to have full control over how the data is submitted
<div id='preview'></div>
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg" id="photoimg" />
</form>
Script File
$('#photoimg').on('change', function()
{
$("#imageform").ajaxForm({target: '#preview', //Shows the response image in the div named preview
success:function(){
},
error:function(){
}
}).submit();
});
ajaximage.php
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST")
{
$name = $_FILES['photoimg']['name'];
$size = $_FILES['photoimg']['size'];
$tmp = $_FILES['photoimg']['tmp_name'];
$path = "uploads/";
move_uploaded_file($tmp, $path.$name) //Stores the image in the uploads folder
}
You could get the values of fields like action,route etc using $_POST inside the php file.For mare details check the below link mate.. :)
http://malsup.com/jquery/form/#ajaxForm

Load Dojo form from ajax call

I am trying to implement something like this.
http://app.maqetta.org/mixloginstatic/LoginWindow.html
I want the login page to load but if you click the signup button then an ajax will replace the login form with the signup form.
I have got this to work using this code
dojo.xhrGet({
// The URL of the request
url: "'.$url.'",
// The success callback with result from server
load: function(newContent) {
dojo.byId("'.$contentNode.'").innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});'
the only problem is the new form just loads up as a normal form, not a dojo form. I have tried to return some script with the phaser but it doesnt do anything.
<div id="loginBox"><div class="instructionBox">Please enter your details below and click <a><strong>signup</strong>
</a> to have an activation email sent to you.</div>
<form enctype="application/x-www-form-urlencoded" class="site-form login-form" action="/user/signup" method="post"><div>
<dt id="emailaddress-label"><label for="emailaddress" class="required">Email address</label></dt>
<dd>
<input 0="Errors" id="emailaddress" name="emailaddress" value="" type="text"></dd>
<dt id="password-label"><label for="password" class="required">Password</label></dt>
<dd>
<input 0="Errors" id="password" name="password" value="" type="password"></dd>
<dt id="captcha-input-label"><label for="captcha-input" class="required">Captcha Code</label></dt>
<dd id="captcha-element">
<img width="200" height="50" alt="" src="/captcha/d7849e6f0b95cad032db35e1a853c8f6.png">
<input type="hidden" name="captcha[id]" value="d7849e6f0b95cad032db35e1a853c8f6" id="captcha-id">
<input type="text" name="captcha[input]" id="captcha-input" value="">
<p class="description">Enter the characters shown into the field.</p></dd>
<dt id="submitButton-label"> </dt><dd id="submitButton-element">
<input id="submitButton" name="submitButton" value="Signup" type="submit"></dd>
<dt id="cancelButton-label"> </dt><dd id="cancelButton-element">
<button name="cancelButton" id="cancelButton" type="button">Cancel</button></dd>
</div></form>
<script type="text/javascript">
$(document).ready(function() {
var widget = dijit.byId("signup");
if (widget) {
widget.destroyRecursive(true);
}
dojo.parser.instantiate([dojo.byId("loginBox")]);
dojo.parser.parse(dojo.byId("loginBox"));
});
</script></div>
any advice on how i can get this to load as a dojo form. by the way i am using Zend_Dojo_Form, if i run the code directly then everything works find but through ajax it doesnt work. thanks.
update
I have discovered that if I load the form in my action and run the __toString() on it it works when i load the form from ajax. It must do preparation in __toString()
Firstly; You need to run the dojo parser on html, for it to accept the data-dojo-type (fka dojoType) attributes, like so:
dojo.parser.parse( dojo.byId("'.$contentNode.'") )
This will of course only instantiate dijits where the dojo type is set to something, for instance (for html5 1.7+ syntax) <form data-dojo-type="dijit.form.Form" action="index.php"> ... <button type="submit" data-dojo-type="dijit.form.Button">Send</button> ... </form>.
So you need to change the ajax contents which is set to innerHTML, so that the parser reckognizes the form of the type dijit.form.Form. That said, I urge people into using a complete set of dijit.form.* Elements as input fields.
In regards to:
$(document).ready(function() {});
This function will never get called. The document, youre adding innerHTML to, was ready perhaps a long time a go.
About Zend in this issue:
Youre most likely rendering the above output form from a Zend_ Dojo type form. If the renderer is set as programmatic, you will see above html a script containing a registry for ID=>dojoType mappings. The behavior when inserting <script> as an innerHTML attribute value, the script is not run under most circumstances (!).
You should try something similar to this pseudo for your form controller:
if request is ajax dojoHelper set layout declarative
else dojoHelper set layout programmatic

Fetching file path from file upload control in mvc using jquery is not working in FIREFOX

I have an mvc textbox control and fileupload control as shown in the image. and here is the markup and js code and the action method....
<div>
<div>
<input type="text" id="txtusername" /></div>
<div>
<input type="file" id="fileupload" /></div>
<div>
</div>
<div>
<input type="button" id="btnsubmit" value="update/submit" onclick="fnupdatedetails(this)" /></div>
[HttpPost]
public ActionResult UpdateDetails(FormDetailsBE formDetailsBE)
{
return View();
}
public class FormDetailsBE
{
public string UserName { get; set; }
public string FileUpload { get; set; }
}
Here is the js code...for IE which is fetching the file path correctly
Here is the js code... for firefox which is not fetching the file path
the same js code acting differently in diff browsers... some one please help. i'm stuck. Thanks in advance.
That's not allowed for security reasons. The client side file path is never sent to the server. There was a bug in older versions of Internet Explorer where this path was sent but in new versions but this bug is fixed in the recent version. The server shouldn't need to know the file path on the client computer.

ASP.NET MVC 3 - File Upload

I have an ASP.NET MVC 3 application. I need to implement a file uploader action within it. For some reason, when I post my form, the Request.Files collection is empty. I have been able to confirm this by setting a breakpoint. So I know that I'm reaching the action. However, I can't figure out why the Request.Files collection is empty. Here are my relevant HTML, AreaRegistration, and Controller snippets.
index.html
<form action="/files/upload/uniqueID" method="post" enctype="multipart/form-data">
<div>Please choose a file to upload.</div>
<div><input id="fileUpload" type="file" /></div>
<div><input type="submit" value="upload" /></div>
</form>
MyAreaRegistration.cs
context.MapRoute(
"FileUpload",
"files/upload",
new { action = "UploadFile", controller = "Uploader" }
);
UploaderController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadFile(int uniqueID)
{
foreach (string file in Request.Files)
{
// I never get here :(
}
return View();
}
I have not made any changes to the default web.config file. Is there some setting I need to add? I can't figure out why the Request.Files collection would be empty. Can someone please help me?
Thank you so much!
You should use HttpPostedFileBase for you controller and do something like that
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
And for the view
<form action="" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<input type="submit" />
</form>
Check Phil Haack blog here for this problem: Uploading a File (Or Files) With ASP.NET MVC
I believe the problem is with your action attribute in your <form /> tag:
action="/files/upload/uniqueID"
I think upon post it is trying to pass the string "uniqueID" to your Action method. When you hit your breakpoint, what is the value of your uniqueID parameter set to when you reach the action method UploadFile()?
Use the HtmlHelper.BeginForm() method to use Razor to construct the form.

mvc3 file upload using ajax form - Request.Files empty

Im using mvc3, and am trying to create a series of ajax forms that each upload a file, within a single page. Here's the view for the page:
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
<script type="text/javascript">
function Go() {
// loop through form tags
for (var n = 0; n < document.forms.length; n++) {
var f = document.forms[n];
// if a dress is chosen, a caption is chosen
// and a file is chosen, then submit the ajax form
if (f.dressid.value != '' &&
f.dresscaption.value != '' &&
f.fileitem.value != '')
f.submit();
}
}
</script>
<input type="button" onclick="Go();"/>
Then the Go() function loops through the ajax forms, checking to see whether all 3 pieces (dressid, dresscaption, and fileitem) on each form are non-empty, and calls submits the forms that do, kicking off an async upload.
Here's the partial view:
#using SoRefeising.Models
#using (Ajax.BeginForm("UploadFile", new { }, new AjaxOptions { HttpMethod = "POST" }, new { enctype="multipart/form-data"}))
{
List<SelectListItem> items = (List<SelectListItem>)ViewBag.Dresses;
<span>Dress</span>
#Html.DropDownList("dressid", items, "Choose Dress");
<span>Caption</span>
#Html.TextBox("dresscaption")
<input type="file" id="fileitem" />
}
I have marked each form with the multipart attribute. When the page is generated, I get the following:
<form action="/upload/UploadFile" data-ajax="true" data-ajax-method="POST" enctype="multipart/form-data" id="form0" method="post"> <span>Dress</span>
<select id="dressid" name="dressid"><option value="">Choose Dress</option>
<option value="1">Simpson01</option>
<option value="2">Simpson02</option>
</select> <span>Caption</span>
<input id="dresscaption" name="dresscaption" type="text" value="" /> <input type="file" id="fileitem" />
</form>
<form action="/upload/UploadFile" data-ajax="true" data-ajax-method="POST" enctype="multipart/form-data" id="form1" method="post"> <span>Dress</span>
<select id="dressid" name="dressid"><option value="">Choose Dress</option>
<option value="1">Simpson01</option>
<option value="2">Simpson02</option>
</select> <span>Caption</span>
<input id="dresscaption" name="dresscaption" type="text" value="" /> <input type="file" id="fileitem" />
</form>
<form action="/upload/UploadFile" data-ajax="true" data-ajax-method="POST" enctype="multipart/form-data" id="form2" method="post"> <span>Dress</span>
<select id="dressid" name="dressid"><option value="">Choose Dress</option>
<option value="1">Simpson01</option>
<option value="2">Simpson02</option>
</select> <span>Caption</span>
<input id="dresscaption" name="dresscaption" type="text" value="" /> <input type="file" id="fileitem" />
</form>
Everything looks ok...
Here's the controller action that is called
[HttpPost]
public ActionResult UploadFile(string dressid, string dresscaption)
{
HttpPostedFileBase hpf = Request.Files[0] as HttpPostedFileBase;
...
When the action is called, the Request.Files collection has 0 items, rather than the selected file. I have enabled unobtrusive javascript, the unobtrusive file is loaded in the master page, and works on other pages.
Ive seen some messages on the forum about being careful with file sizes. The file I am testing with is < 2k
Any ideas why there are no items in Request.Files?
Thanks
You cannot upload files using AJAX. So replace the Ajax.BeginForm with a normal Html.BeginForm. You may checkout the following blog post as well.
If you want to use asynchronous uploads you may try some of the available upload components such as Ajax Upload and Uploadify.
First of all, I am not sure why you have this three times.
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
#Html.Partial("_UploadItem")
Are you trying to upload multiple files? There are quite a few scripts that allow you to do this quite efficiently. You are also generating multiple forms with fields that contain the same id. This wont effect the upload process, but is bad practice. I do think you need to refactor the above. Anyway change the field in your partial view to
<input type="file" name="file" />
I think the problem may be with your actual action and how you are trying to retrieve the file. Try this
HttpPostedFileBase postedFile = Request.Files["file"];
Let me know if that works.

Resources