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.
Related
I try to change the value of an input button after it was clicked. The button itself is an submit button, and the controller is getting back to the page by RedirectToAction. My problem is, that I can change the value of the button, but this new value is only shown for a millisecond before it is set back to its original value. Is the page reloaded after the script fired? Or why is the button value set back after the script fired?
Here is my code:
The button:
#using (Html.BeginForm("StartNewM2OLIEProcess", "Patient", new { label = Model.PatientID }, FormMethod.Post))
{
<input type="submit" id="btnStartProcess" value="M²OLIE Prozess starten" class="btn btn-primary" />
}
The Script
#section Scripts{
<script type="text/javascript">
$("#btnStartProcess").on('click', function () {
var self = $(this);
var errorMsg = '#errorMsg';
if (errorMsg == '') {
//self.attr('M2OLIE Prozess starten', 'Prozess gestartet');
self.val('Prozess läuft...');
}
else {
self.val("M²OLIE Prozess starten");
}
});
</script>
<script type="text/javascript">
var message = '#message';
if(message){
alert(message);
}
</script>
}
So the scripts are correctly fired, that I could test with the debugger. And I can also see the value of the button changing during debugging, but as soon as the script ends, the value changes back to the value that is defined in the Html form. What is happening here?
When the first click, the jQuery event is executed, then the page is sent to the action.
You either have to post the page or manage the click event.
test this code with your script
$("form").submit(function (e) {
e.preventDefault();
});
I will give you an example to see how the changes after the form post.
In Controller
[HttpGet]
public ActionResult StartNewM2OLIEProcess()
{
return View();
}
[HttpPost]
public ActionResult StartNewM2OLIEProcess(string myText)
{
ViewBag.ButtonText = myText;
return View();
}
In View
#{
ViewBag.Title = "Test";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("StartNewM2OLIEProcess", "Home", FormMethod.Post))
{
string buttonValue = "M²OLIE Prozess starten";
if (!string.IsNullOrEmpty(ViewBag.ButtonText))
{
buttonValue = ViewBag.ButtonText;
}
<input type="text" id="myText" name="myText" />
<input type="submit" id="btnStartProcess" value="#buttonValue" class="btn btn-primary" />
}
<div id="myDiv" style="width:300px;height:50px;background:#FF5511;color:white;text-align:center;font-weight:bold;"></div>
#section scripts{
<script>
var result = '#(ViewBag.ButtonText)';
if (result != null) {
document.getElementById("myDiv").innerText = result;
}
</script>
}
In my MVC, i have a view and that contains one file upload control and one button.
<input type="file" id="Uploadfile" />
<input type="button" onclick()="GetFile();/>
Javascript function as follows
function GetFile()
{
var file_data = $("#Uploadfile").prop("files")[0];
window.location.href="Calculation/Final?files="+file_data;
}
I need to pass/send the selected file via fileupload control to controller in mvc.
i have the controller
public ActionResult Final(HttpPostedFileBase files)
{
//here i have got the files value is null.
}
How to get the selected file and send it to the controller?
Plz help me to fix this issue.
I had similar functionality to deliver in my project.
The working code looks something like this:
Controller Class
[HttpPost]
public ActionResult UploadFile(YourModel model1)
{
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength > 0)
{
string folderPath = Server.MapPath("~/ServerFolderPath");
Directory.CreateDirectory(folderPath);
string savedFileName = Server.MapPath("~/ServerFolderPath/" + hpf.FileName);
hpf.SaveAs(savedFileName);
return Content("File Uploaded Successfully");
}
else
{
return Content("Invalid File");
}
model1.Image = "~/ServerFolderPath/" + hpf.FileName;
}
//Refactor the code as per your need
return View();
}
View
#using (#Html.BeginForm("UploadFile", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<table style="border: solid thin; margin: 10px 10px 10px 10px">
<tr style="margin-top: 10px">
<td>
#Html.Label("Select a File to Upload")
<br />
<br />
<input type="file" name="myfile">
<input type="submit" value="Upload" />
</td>
</tr>
</table>
}
you cannot send file content via javascript (unless HTMl5). and you are doing totally wrong. if you want to do HTML5 based solution via FileReader api then you need to check this out. FileReader Api
Just put a form tag and use the same name of the input in the controller action to perform model binding
#using(Html.BeginForm("yourAction","YourControl",FormMethod.Post))
{
<input type="file" id="fileUpload" />
}
then in controller.
[HTTPPost]
public ActionResult Final(HttpPostedFileBase fileUpload)
{
//here i have got the files value is null.
}
Below code will do a full post back in an hidden form which will give an illusion of ajax file upload. Try it:
Update:
JS
function Upload(sender) {
var iframe = $("<iframe>").hide();
var newForm = $("<FORM>");
newForm.attr({ method: "POST", enctype: "multipart/form-data", action: "/ControllerName/Final" });
var $this = $(sender), $clone = $this.clone();
$this.after($clone).appendTo($(newForm));
iframe.appendTo($("html")).contents().find('body').html($(newForm));
newForm.submit();
}
HTML
<input type="file" id="Uploadfile" name="Uploadfile" />
<input type="button" onclick="Upload($('#UploadFile'));"/>
Controller
public ActionResult Final(HttpPostedFileBase Uploadfile)
{
//here you can use uploaded file
}
As a completion from Ravi's answer, I would suggest to use the following using statement:
#using(Html.BeginForm("yourAction","YourControl",FormMethod.Post, new { enctype="multipart/form-data" }))
{
<input type="file" id="fileUpload" />
}
You can do it by using json data to view.
As instance,
Controller
public ActionResult Products(string categoryid)
{
List<catProducts> lst = bindProducts(categoryid);
return View(lst);
}
public JsonResult Productsview(string categoryid)
{
//write your logic
var Data = new { ok = true, catid = categoryid};
return Json(Data, JsonRequestBehavior.AllowGet);
}
View:
#{
ViewBag.Title = "Index";
}
#model ASP.NETMVC.Controllers.Categories
<h2>List Of Categories</h2>
#Html.ListBox("lst_categories", (IEnumerable<SelectListItem>) ViewBag.Categories)
<script type="text/javascript">
$(function () {
$('#lst_categories').change(function () {
var catid = $('#lst_categories :selected').val();
$.ajax({
url: '#Url.Action("Productsview", "Jquery")',
type: 'GET',
dataType: 'json',
data: { categoryid: catid },
cache: false,
success: function (Data) {
if (Data.ok) {
var link = "#Url.Action("Products", "Jquery", new { categoryid = "catid" })";
link = link.replace("catid", Data.catid);
alert(link);
window.location.href = link;
}
}
});
});
});
</script>
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.
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.
I want to have a menu that when I click replaces the content of a "main" div with content from a mvc view. This works just fine if I use a .aspx page, but any master.page content is then doubled (like the and any css/js). If I do the same but uses a .ascx user control the content is loaded without the extras, but if any browser loads the menu item directly (ie search bot's or someone with JS disabled), the page is displayed without the master.page content.
The best solution I've found so far is to create the content as a .ascx page, then have a .aspx page load this if it's called directly from the menu link, while the ajax javascript would modify the link to use only the .ascx. This leads to a lot duplication though, as every user control needs it's own .aspx page.
I was wondering if there is any better way of doing this? Could for example the master.page hide everything that's not from the .aspx page if it was called with parameter ?ajax=true?
We've solved this by using a baseController class that all controllers inherit from, and using an override for OnActionExecuted:
/// <summary>
/// Changes the masterpage to a slim version in AjaxRequest
/// </summary>
/// <param name="filterContext"></param>
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
var action = filterContext.Result as ViewResult;
if (action != null && Request.IsAjaxRequest())
{
action.MasterName = "Ajax";
}
base.OnActionExecuted(filterContext);
}
The "Ajax" master page is a then a simple masterpage with only 1 contentPlaceHolder. This works fine as long as all aspx pages that can be called with ajax only uses this placeholder.
What about making an ActionMethod that changes what it renders depending on the type of http request it gets? So if it is an ajax request it would render the ascx but if it is not, then it can render the whole view (or redirect to another action that renders the whole view)?
something like
public ActionResult Section1()
{
if (Request.IsAjaxRequest())
{
return PartialView("section1.ascx");
}
return View("section.aspx");
}
and i guess section.aspx coud have inside a RenderPartial(section1.ascx) (so you dont do the page twice).
Here is an example of the method I use with great success:
In the View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Namespace.Stuff>>" %>
<asp:Content ID="Content3" ContentPlaceHolderID="head" runat="server">
<script type="text/javascript">
$(document).ready(function(){
$("#optionsForm").submit(function() {
$("#loading").dialog('open');
$.ajax({
type: $("#optionsForm").attr("method"),
url: $("#optionsForm").attr("action"),
data: $("#optionsForm").serialize(),
success: function(data, textStatus, XMLHttpRequest) {
$("#reports").html(data); //replace the reports html.
$("#loading").dialog('close'); //hide loading dialog.
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$("#loading").dialog('close'); //hide loading dialog.
alert("Yikers! The AJAX form post didn't quite go as planned...");
}
});
return false; //prevent default form action
});
});
</script>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div id="someContent">
<% using (Html.BeginForm("Index", "Reports", FormMethod.Post, new{ id = "optionsForm" }))
{ %>
<fieldset class="fieldSet">
<legend>Date Range</legend>
From: <input type="text" id="startDate" name="startDate" value="<%=ViewData["StartDate"] %>" />
To: <input type="text" id="endDate" name="endDate" value="<%=ViewData["EndDate"] %>" />
<input type="submit" value="submit" />
</fieldset>
<%} %>
</div>
<div id="reports">
<%Html.RenderPartial("ajaxStuff", ViewData.Model); %>
</div>
<div id="loading" title="Loading..." ></div>
</asp:Content>
In the Controller:
public ActionResult Index(string startDate, string endDate)
{
var returnData = DoSomeStuff();
if (Request.IsAjaxRequest()) return View("ajaxStuff", returnData);
return View(returnData);
}