Ajax.beginForm not posting Files to Controller - asp.net-mvc

I am working on MVC. I have a form to send Email. The razor form is below
#Ajax.BeginForm("sendEmail", "communication", new AjaxOptions() { OnBegin = "return onBeginFun();", UpdateTargetId = "emailMessage" }, new { id = "communicationForm", enctype = "multipart/form-data" })
{
#Html.TextAreaFor(m => m._Email.Body, new { #class = "form-control editor overflow:scroll; max-height:300px", name = "emailbody", id = "emailbody" })
<input type="file" id="fileUploader" name="fileUploader" multiple ;" />
<button type="submit" id="submitCommunication"> SAVE>>></button>
}
The controller is as follows
[HttpPost]
[ValidateInput(false)]
public async Task<JsonResult> sendEmail(CommunicationModelView P_CMV, HttpPostedFileBase fileUploader)
{
....................
}
Upon clicking submit button I can see the Model filled with the form data, but fileUploader is null even though I have selected file(s).
Need help.
Thanks in advance.

Related

I can't send a POST request from view to Controller in ASP.NET MVC

I have this form shown below:
#using (Html.BeginForm("NewArticle", "News",FormMethod.Post, new { name = "createForm", onsubmit = "return validateFormNewPost()" }))
{
#Html.TextBoxFor(p => p.adName, new { #class="form-control"})
#Html.DropDownListFor(p => p.tyepId, listType, "---Select Type---", new { #class = "form-control" })
#Html.TextBox("imgPath", "", new { #class = "form-control", id = "imgPath" })
#Html.TextAreaFor(p =>p.AdDescription,new { id = "editor" })
<button class="btn btn-reset btn-dark" type="reset">Reset</button>
<button class="btn-submit btn-primary btn" type="submit">Submit</button>
}
Controller:
[HttpGet]
public ActionResult NewArticle()
{
List<AdType> listType = typeModel.listForAdd();
SelectList s = new SelectList(listType, "id", "AdType1");
ViewBag.ListType = s;
return View();
}
[HttpPost]
public ActionResult NewArticle(Advertisement model,string imgPath)
{
// my code
return RedirectToAction("Category","News");
}
I'm trying to make a POST request by submit the form but it always send form data with a GET request. How can I fix it?
How are you sending the POST? Are you using AJAX or JavaScript from your MVC page or are you trying to hit the endpoint with an external application like Telerik Fiddler or Postman?
You can not make a POST request directly from the browser using the URL, my assumption is that may be what you are doing.
#using (Html.BeginForm("MethodNameinController", "Controller Name", FormMethod.Post))
{
//form fields with submit button
<input type="submit" value="Save" class="btn btn-default" id="create" />
}
And in Controller
[HttpPost]
public ActionResult MethodNameinController(Model model)
{
}

Image upload using #Ajax.BeginForm in .NET MVC?

I want to upload image using Ajax.BeginForm in my application.
Currently HttpPostedFileBase file is getting value 0. Anyone Please guide me here.
I have tried this code but file is not uploading.
Appreciated, if anyone can provide some solutions for this. If I use #Html.BeginForm then It works but I want to use #Ajax.BeginForm.
Model
public class ClsUpload
{
public string FilePath { get; set; }
}
Controller
public ActionResult Edit(ClsUpload model,HttpPostedFileBase file)
{
if (Request.Files.Count > 0)
{
file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
string fileName = Path.GetFileName(file.FileName);
string path = Path.Combine(Server.MapPath("/Content/Images/"), fileName);
file.SaveAs(path);
model.FilePath = path;
}
}
try
{
UploadDetials details = new UploadDetials();
details.UpdateDetails(model);
return RedirectToAction("Index");
}
catch
{
return RedirectToAction("Index");
}
}
Partial View
#model XX.X.Models.File.ClsUpload
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "partial", InsertionMode = InsertionMode.Replace }))
{
#Html.HiddenFor(model => model.FilePath)
<input type="file" name="file" />
<img src=#Model.FilePath alt="Image" />
<input type="submit" value="Save" />
}
You can update your code with FormMethod.Post, new { enctype = "multipart/form-data" }) and [AcceptVerbs(HttpVerbs.Post)] as follow
In Partial View
#using (Html.BeginForm("ActionMethod1", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
In Controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ActionMethod1(HttpPostedFileBase pic)
{
}
This is old, but I want to show how I have accomplished uploading a file using Ajax.BeginForm(). Basically, the overloads will tell you what is possible. I use the overload for: "string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes". Note: I use null for "routeValues".
Here is a code example:
#using (Ajax.BeginForm("UploadFile", "Home", null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "MyIDToUpdate", OnSuccess = "EditSuccessClearForm('IDToClear', '')", OnFailure = String.Format("NewGenericFailure(xhr, '{0}')", "#IDToPassThisFunction"), InsertionMode = InsertionMode.ReplaceWith }, new { enctype = "multipart/form-data", #id = "NewFileFormID" }))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-sm-8 col-sm-offset-1">
#Html.TextBox("file", "", new { type = "file", accept = ".jpg, .jpeg, .png, .pdf", #id = fileID, onchange = VerifySizeOfFile })
</div>
<div class="col-sm-2">
<button type="submit" id="FileSubmitButton" class="btn btn-primary">Upload</button>
</div>
</div>
}

Cancel button on MVC

When the client click on Cancel (on ItemsOptions) he should go back to the previous page (Client):
I added in the View ItemsOptions:
#using (Html.BeginForm("","", FormMethod.Post, new { #class = "form-group", role = "form" }))
{
<div class="col-md-4"><input id = "theCancel" class="cancel" type="submit" value="Cancel" /></div>
}
When the Button Cancel is hit the error Message :
The required anti-forgery form field "__RequestVerificationToken" is not present.
I added in the controller
[ValidateAntiForgeryToken]
public ActionResult ***Client***(OrderItems model)
{
}
and in the Client View
#using (Html.BeginForm("Client", "Home", FormMethod.Post, new { #class = "form-group", role = "form" }))
{
#Html.AntiForgeryToken();
}
I tried another way:
I added in the View ItemsOptions:
#using (Html.BeginForm("","", FormMethod.Post, new { #class = "form-group", role = "form" }))
{
<div class="col-md-4"><input class="btn btn-warning" type="submit" value="Cancel" name="action:Cancel" /></div>
}
the controller
[MultipleButton(Name = "action", Argument = "Cancel")]
public ActionResult Cancel(OrderItems model)
{
return View("Client", model);
}
How can I implement the cancel button in the MVC form,I want the user to go to the previous page.
Thanks
If you just want the cancel button to go back
<script type='text/javascript'>
function goBack() {
window.history.back();
}
</script>
<!--cancel button-->
<button onclick='goBack()'>Cancel</button>
Does something like this work for you?

Upload a File with MVC HttpPostedFileBase == null

My Controller
public ActionResult Edit(int id)
{
return this.EditDefault(id);
}
[HttpPost]
public ActionResult Edit(int id, Models.Company model)
{
return this.EditDefault(id, model);
}
My Model
pulbic class Company
{
... Many other Propeties
public HttpPostedFileBase File { get; set; }
}
My View
#using (Html.BeginForm(new { enctype = "multipart/form-data" }))
{
... Many other Properties
#Html.TextBoxFor(m => m.File, new
{
type = "file", style = "display:none"
})
... Submit
}
So my problem now is when I submit the page the infos in the model are right, but the File Property is still null.
I found some solutions where people added HttpPostedFileBase as parmeter in the controller (tried it doesn't work too), but I would like to avoid that anyway because the model and the controller are generated with T4. So has someone an idea why the File Property is always null?
Would be really happy about some help :)
Update: Found the solution thx to Matt Tabor.
For me the solution looks like this because I use a shared Edit page.
The javascript part is to hide the actual file upload element and use a span instead, because the file upload isn't style able.
//Shared Part
#{
RouteData routeData = this.ViewContext.RouteData;
string currentController = routeData.GetRequiredString("controller");
}
#using (Html.BeginForm("Edit", currentController, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//Special Part
... Many other Properties
//File upload which is hidden
#Html.TextBoxFor(m => m.File, new
{
type = "file", style = "display:none"
})
//Span which forwards the clicks to the file upload
<span id="fake-file-name">Kein Bild</span>
... Submit
}
<script type="text/javascript">
$(function () {
//forward the click from the span to the file upload
$("#fake-file-name").click(function () {
$("#File").click();
});
//display the chosen file name to the user with the styled span
$("#File").bind('change', function () {
//we don't want the C:\fakepath to show
var displayFileName = this.value.replace("C:\\fakepath\\", "");
$("#fake-file-name").text(displayFileName);
});
});
</script>
you need to specify your form method as post
#using (Html.BeginForm("Edit", "CONTROLLER", null,FormMethod.Post, new { enctype = "multipart/form-data" }))
#Html.TextBoxFor(m => m.File, new
{
type = "file", style = "display:none"
})
Instead have a Input type file as shown below -
<input type="file" name="File" id="File"/>
PS: Name should match to Model property name.
UPDATE
Remove display:none from your code and it should work fine.

MVC How to change a buttons text on submit

I'm trying to create a simple MVC 4 app with a few buttons that when clicked adds one to their text value. The problem is when I use < input > buttons I can't change the text value when I submit the form and when I use < button > then there is nothing passed to the action.
I have a simple SQL Database that the controller hits which is where the initial ViewData values are coming from and how it's storing the buttons current value.
Also I'm currently trying to do this with multiple forms but if it is possible with one form then that would be ideal.
#using (Ajax.BeginForm("AddOne", "Home", null, new AjaxOptions { UpdateTargetId = "btn-tc-top"}, new { #class = "rectangle-top" }))
{
<input type="submit" class="button" name="button" id="btn-tc-top" value="#ViewData["ct-t"]"/>
}
#using (Ajax.BeginForm("AddOne", "Home", null, new AjaxOptions { UpdateTargetId = "btn-tc-bottom"}, new { #class = "rectangle-bottom" }))
{
<button type="submit" class="button" name="button" id="btn-tc-bottom">#ViewData["ct-b"]</button>
}
You could subscribe to the OnSuccess handler:
#using (Ajax.BeginForm("AddOne", "Home", new { id = "btn-tc-top" }, new AjaxOptions { OnSuccess = "addSuccess" }, new { #class = "rectangle-top" }))
{
<input id="btn-tc-top" class="button" type="submit" name="button" value="#ViewData["ct-t"]" />
}
#using (Ajax.BeginForm("AddOne", "Home", new { id = "btn-tc-bottom" }, new AjaxOptions { OnSuccess = "addSuccess" }, new { #class = "rectangle-bottom" }))
{
<input id="btn-tc-bottom" class="button" type="submit" name="button" value="#ViewData["ct-b"]" />
}
which could be defined like this:
function addSuccess(result) {
$('#' + result.id).val(result.text);
}
and the controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["ct-t"] = "1";
ViewData["ct-b"] = "2";
return View();
}
[HttpPost]
public ActionResult AddOne(string id, int button)
{
return Json(new { id = id, text = button + 1 });
}
}

Resources