MVC - Cannot seem to post to controller action using AJAX helper - asp.net-mvc

I'm having issues posting a model to a controller action using the AJAX helper. The controller action doesn't get hit at all.
Code:
View:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ServiceNumberModel>" %>
<div id="ServiceNumberPanel">
<h1>
Based on your location we offer different plans</h1>
<% using (Ajax.BeginForm("AvailablePlans", "ServiceCheck", new AjaxOptions { UpdateTargetId = "AdslPlansPanel", HttpMethod = "Post" } ))
{ %>
<%=Html.ValidationSummary(true)%>
Your Phone Number:
<%=Html.TextBoxFor(m => m.HomePhoneNumber)%><br />
<%=Html.CheckBoxFor(m => m.BundleWithHomePhone)%>Bundle with Home Phone? <br/>
<input id="CheckServiceAvailabilityButton" type="submit" value="Check"/>
<% } %>
</div>
Model:
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace ServiceCheck
{
public class ServiceNumberModel
{
[Required(ErrorMessage = "Please enter your phone number.")]
[RegularExpression(#"^[0]\d{9}$", ErrorMessage = "Please enter your phone number, including the area code")]
[DisplayName("Phone Number:")]
public string HomePhoneNumber { get; set; }
public bool BundleWithHomePhone { get; set; }
}
}
Controller:
[HttpPost]
public ActionResult AvailablePlans(ServiceNumberModel serviceNumberModel)
{
if (serviceNumberModel.BundleWithHomePhone)
return ReturnAvailableBundledPlans(serviceNumberModel);
return View("Index");
}
Generated HTML:
<div id="ServiceNumberPanel">
<h1>
Based on your location we offer different plans</h1>
<form action="/ServiceCheck/AvailablePlans" data-ajax="true" data-ajax-method="Post" data-ajax-mode="replace" data-ajax-update="#AdslPlansPanel" id="form0" method="post">
Your Phone Number:
<input data-val="true" data-val-regex="Please enter your phone number, including the area code" data-val-regex-pattern="^[0]\d{9}$" data-val-required="Please enter your phone number." id="HomePhoneNumber" name="HomePhoneNumber" type="text" value="" /><br />
<input data-val="true" data-val-required="The BundleWithHomePhone field is required." id="BundleWithHomePhone" name="BundleWithHomePhone" type="checkbox" value="true" /><input name="BundleWithHomePhone" type="hidden" value="false" />Bundle with Home Phone? <br/>
<input id="CheckServiceAvailabilityButton" type="submit" value="Check"/>
</form>
</div>
Behaviour:
When I click on submit, I get 'Resource cannot be found error':
The resource cannot be found. Description: HTTP 404. The resource you
are looking for (or one of its dependencies) could have been removed,
had its name changed, or is temporarily unavailable. Please review
the following URL and make sure that it is spelled correctly.
Requested URL: /ServiceCheck
Interestingly when I look at the source using firebug, I cannot see the form tags:
<div class="ExistingContent">
<h1>ServiceCheck</h1>
<div id="ServiceNumberPanel">
<div id="ServiceNumberPanel">
<h1> Based on your location we offer different plans</h1>
Your Phone Number:
<input id="HomePhoneNumber" type="text" value="" name="HomePhoneNumber" data-val-required="Please enter your phone number." data-val-regex-pattern="^[0]\d{9}$" data-val-regex="Please enter your phone number, including the area code" data-val="true">
<br>
<input id="BundleWithHomePhone" type="checkbox" value="true" name="BundleWithHomePhone" data-val-required="The BundleWithHomePhone field is required." data-val="true">
<input type="hidden" value="false" name="BundleWithHomePhone">
Bundle with Home Phone?
<br>
<input id="CheckServiceAvailabilityButton" type="submit" value="Check">
</div>
<div id="Div1">
</div>
</div>
Also, if I change the view to use the HTML helper it hits the controller without issue:
<div id="Div1">
<h1>
Based on your location we offer different plans</h1>
<% using (Html.BeginForm("AvailablePlans", "ServiceCheck"))
{ %>
<%=Html.ValidationSummary(true)%>
Your Phone Number:
<%=Html.TextBoxFor(m => m.HomePhoneNumber)%><br />
<%=Html.CheckBoxFor(m => m.BundleWithHomePhone)%>Bundle with Home Phone? <br/>
<input id="Submit1" type="submit" value="Check"/>
<% } %>
</div>
Please help!!!

I managed to find the issue.
In the master page I was using, which is shared across a number of applications, someone had added a rouge form:
<body>
<form id="form1" runat="server">
<uc1:header id="Header1" runat="server" />
<div class="ExistingContent">
<asp:contentplaceholder id="MainContent" runat="server" />
</div>
<uc2:footer id="Footer1" runat="server" />
</form>
</body>
This meant that I was trying to submit a form from within a form and the framework was defaulting to the parent.
Once removed, everything began to work as expected.

Related

Is it possible to include a file with a form POST

I got a regular POST in my mvc app:
#using (Html.BeginForm("Update", "AController", FormMethod.Post))
{
<div style="margin-bottom:20px"></div>
#Html.AntiForgeryToken()
<div class="form-input">
<input class="form-control" type="text" name="#(nameof(Model.Name))" value="#(Model.Name)" />
</div>
<br />
<div class="form-input">
<input class="form-control" type="text" name="#(nameof(Model.Name2))" value="#(Model.Name2)" />
</div>
<br />
<div>
<input type="file" name="Image" id="Image" name="#(nameof(Model.Image))" value="#(Model.Image)" />
</div>
<button type="submit" class="btn btn-primary btn-sm">TEXT HERE</button>
}
Now when doing the submit the two regular text fields gets binded the model but the file does not.
After some reading it seems like the upload part should be in a separate form, is that correct?
I really want to avoid having two different POST as it does not fit the design of the page.
You should be able to get the posted file from the Request directly in the controller with following code
if(Request.Files.Count > 0)
{
var file = Request.Files[0];
...
}
But you need to add the multipart/form-data to your form
#using (Html.BeginForm("Update", "AController", FormMethod.Post, new { enctype="multipart/form-data" }))
Check What does enctype='multipart/form-data' mean? for reference on the multipart/form-data

Get method : form input not in url

I am doing my first ASP.NET mvc project, on the home page, Index.cshtml, I have a small form:
<form action="ChoixFormulaire" method="get">
<fieldset>
<label>NAS</label>
<input id="nas" type="text" placeholder="###"/>
<br />
<label>Date of birth</label>
<input id="date" type="text" placeholder="AAAA-MM-JJ"/>
<br />
<label>Employee number</label>
<input id="numEmployee" type="text" placeholder="######"/>
<br />
</fieldset>
<input type="submit" value="Soumettre" onclick="return VerifierFormulaire()" />
</form>
When the button is clicked, there is some verification made in the 'VerifierFormulaire()' method, which is defined in the same Index.cshtml file. Then the ChoixFormulaire.cshtml is displayed (called from the ChoixFormulaire() method in my HomeController, which returns View()).
I was expecting the form inputs to be in the URL as parameters. For example, If I enter '123' for NAS, '1989-01-01' for date of birth and '123456' for employee number, I am redirected to http://localhost:15778/Home/ChoixFormulaire? but I would expect to be redirected to http://localhost:15778/Home/ChoixFormulaire?nas=123&dateBirth=1989-01-01&numEmployee=123456
Try adding the name attribute:
<input id="nas" name="nas" />

Html.ValidationMessageFor not displaying at all

I have the following form:
<form action="~/buy-online" method="get" class="buy-online-form clearfix" autocomplete="off" id="buy-online-search">
<div class="infield-holder clearfix">
#Html.LabelFor(m => m.CustomerPostcode, new { #class = "infield" })
#Html.TextBoxFor(m => m.CustomerPostcode, new { #class = "textbox" })
<input type="submit" value="Buy Online" id="find-retailer-button" class="button" />
</div>
</form>
#Html.ValidationMessageFor(m => m.CustomerPostcode)
Which works fine and will display an error message when submitted without jQuery, but when I add the jQuery validate scripts (v 1.11.1):
<script src="/scripts/jquery.validate.js"></script>
<script src="/scripts/jquery.validate.unobtrusive.js"></script>
It stops the form submitting but doesn't display the error message
My property is marked like so:
[DisplayName("Enter your full postcode")]
[Required(ErrorMessage = "Please enter your full postcode")]
public string CustomerPostcode { get; set; }
And the html renders like this:
<input class="textbox" data-val="true" data-val-required="Please enter your full postcode" id="CustomerPostcode" name="CustomerPostcode" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="CustomerPostcode" data-valmsg-replace="true"></span>
If I inspect the input when I hit submit it is adding the class input-validation-error to the textbox but just not updating the validation message.
All the posts that I have checked on this problem just say to include the scripts so I'm at a loss as to why the message is not showing.
I've even tried adding the jquery.unobtrusive-ajax.js script but that didn't seem to do anything either. Any help would be appreciated, thanks.
You need to include the #Html.ValidationMessageFor(m => m.CustomerPostcode) within the form tags for jquery.validate.unobtrusive to work.

MVC Display Data

Following this MVC Tutorial, but cannot get the display customer view to display after input the data. I don't see anything I do wrong
http://www.codeproject.com/Articles/207797/Learn-MVC-Model-View-Controller-step-by-step-in-7
here is my fill customer
<div>
<form action="DisplayCustomer.aspx" method="post">
Enter Customer Code: <input type="text" name="CustomerCode" /><br />
Enter Customer Name: <input type="text" name="CustomerName" /><br />
Ennter Customer Amout: <input type="text" name="CustomerAmount" /><br />
<input type="submit" value="Submit customer data" />
</form>
</div>
here is my display customer
public ActionResult DisplayCustomer()
{
Customer localCustomer = new Customer();
localCustomer.Code = Request.Form["CustomerCode"].ToString();
localCustomer.Name = Request.Form["CustomerName"].ToString();
localCustomer.Amount = Convert.ToDouble(Request.Form["CustomerAmount"].ToString());
return View(localCustomer);
}
then
<div>
The name of the customer is: <%:Model.Name = "test" %>
<br />
The code of the customer is: <%:Model.Code %>
<br />
The amout refund to the customer is: <%:Model.Amount%>
</div>
seems like something is wrong with the steps
I got this error when I tried
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /customer/DisplayCustomer.aspx
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.17929
The correct path for the request is /customer/displaycustomer
The .aspx extension gets handled in a different way, so the MVC Routing Engine is never fired, and as that page doesn't exist at that path the result is a 404 error.
You actually need to remove .aspx extension. Just request the page as /Customer/DisplayCustomer.
As a side note, you may need to update your form aswell and remove the aspx extension, eg:
<form action="DisplayCustomer" method="post">
Enter customer id :- <input type="text" name="Id" /> <br />
Enter customer code :- <input type="text" name="CustomerCode" /><br />
Enter customer Amount :-<input type="text" name="Amount" /><br />
<input type="submit" value="Submit customer data" />
</form>
replaced the line:
<form action="DisplayCustomer.aspx" method="post">
to
<form action="DisplayCustomer" method="post">

webform with one text box and two buttons

How can I have two buttons posting to different actions for the same text box?
for eg: I have two buttons "Get Student(xls)" and "Get Student(pdf)" and I want to trigger different ActioResult methods. I am only able to trigger one method for launching excel, which is: "/Student/StudentExcel/" The second method for launching pdf is: "/Student/StudentPdf/".
Here is my screenshot for the form:
Here is my code for the view page:
<%# Page language="c#" AutoEventWireup="true" %>
<%# Import NameSpace="System.IO" %>
<%# Import NameSpace="System" %>
<%# Import NameSpace="System.Data" %>
<%# Import NameSpace="System.Web" %>
<%# Import NameSpace="System.Text" %>
<%# Import Namespace="STUDENT.Controllers" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Get Student File</title>
</head>
<body>
<div>
<form method="post" action="/Student/StudentExcel/">
<label for="id">Student Number: </label>
<input type="text" name="id" value="" />
<br /><br />
<input type="submit" value="GetStudent(xls)"/> &nbsp
<input type="submit" value="Get Student(pdf)" />
</form>
</div>
How can I have two buttons posting to different actions for the same text box?
You can't do this without javascript and plain HTML.
Let me suggest you an alternative: you could use two submit buttons with different names that submit to the same controller action and inside this controller action you could retrieve the name of the submit button that was clicked and act accordingly.
<form method="post" action="/Student/Dispatch/">
<label for="id">Student Number: </label>
<input type="text" name="id" value="" />
<br /><br />
<input type="submit" value="Get Student(xls)" name="xls" />
&nbsp
<input type="submit" value="Get Student(pdf)" name="pdf" />
</form>
and inside the Dispatch action:
[HttpPost]
public ActionResult Dispatch(string pdf, string id)
{
if (!string.IsNullOrEmpty(pdf))
{
// The GetPdf submit button was clicked
return StudentPdf(id);
}
// The GetXls submit button was clicked
return StudentExcel(id);
}

Resources