I am having problems getting my form to Post to my Save method in a controller. I am new to MVC, and have followed several examples to try to get this to work. Here is my html markup:
<form action="Edit/Save" method="post">
<fieldset>
<legend>Personal Information</legend>
<table class="editGrid">
<tr>
<td><label for="txtFirstName">First Name:</label></td>
<td><input type="text" id="txtFirstName" value="<%=user.FirstName %>" name="FirstName" /></td>
</tr>
<tr>
<td><label for="txtLastName">Last Name:</label></td>
<td><input type="text" id="txtLastName" value="<%=user.LastName %>" name="LastName" /></td>
</tr>
<tr>
<td><label for="txtNtLogin">NT Login:</label></td>
<td><input type="text" id="txtNtLogin" value="<%=user.NtLogin %>" name="NtLogin" /></td>
</tr>
<tr>
<td><label for="txtHireDate">Hire Date:</label></td>
<td><input type="text" id="txtHireDate" value="<%=string.Format("{0:d}",user.HireDate) %>" name="HireDate" /></td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>Job Information</legend>
<table class="editGrid">
<tr>
<td><label for="CostCenters">Cost Center:</label></td>
<td><%=Html.DropDownList("CostCenters")%></td>
</tr>
<tr>
<td><label for="Managers">Manager:</label></td>
<td><%=Html.DropDownList("Managers")%></td>
</tr>
<tr>
<td><label for="Responsibilities">Responsibility:</label></td>
<td><%=Html.DropDownList("Responsibilities")%></td>
</tr>
<tr>
<td><label for="Departments">Department:</label></td>
<td><%=Html.DropDownList("Departments")%></td>
</tr>
<tr>
<td><label for="Active">Active:</label></td>
<td><%=Html.CheckBox("Active",user.Active) %></td>
</tr>
<tr>
<td><label for="txtHireDate">Hire Date:</label></td>
<td><%=Html.TextBox("txtHireDate",string.Format("{0:d}",user.HireDate)) %></td>
</tr>
<tr>
<td><label for="txtReleaseDate">Release Date:</label></td>
<td><%=Html.TextBox("txtReleaseDate",string.Format("{0:d}",user.ReleaseDate)) %></td>
</tr>
</table>
</fieldset>
<input type="submit" value="Save Changes" />
</form>
This form routes to a Save method in my EditController. Here is the code for my EditController's Save method:
public class EditController : Controller
{
public ActionResult Save()
{
//Save code goes here
}
I have tried using the html form tag, and also the Html helper code:
using (Html.BeginForm("Save", "Edit"))
Here is the entry from my RegisterRoutes method in the Global.asax file:
routes.MapRoute("EditSave", "{controller}/Save",
new { controller = "Edit", action = "Save" });
No matter what I do, the submit button does not trigger the Save method. Yet, if I manually key in the Url, The code breaks right into the Save method.
Edit:
Per Craig Stuntz's comment, I checked the source of the page. The page actually contains 2 forms, although only 1 is coded on the page by myself: Here is the HTML that appears prior to my form tag:
<form name="aspnetForm" method="post" action="44" id="aspnetForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNjM3OTAyNTUzZGQrHhVn9+t78aHxN0vHvKUJ8DQWlQ==" />
</div>
<div id="nav">
<span id="navLinks">
Placeholder Link
</span>
<span id="userName">
<span id="ctl00_lblUserName" class="UserName">Welcome, Test User</span>
</span>
</div>
<div id="Content">
<div id="formContainer">
<form action="Edit/Save" method="post">
I didn't think MVC generated viewstate or additional form tags. I am pulling data and populating it into this form using another method from the same controller. Am I doing something wrong here?
Ok, got the answer. And thanks Craig for having me look at the HTML again! My master page had generated a form tag in it without my knowing it, so I essentially had nested forms on the same page. After I removed the form from the Master Page, everything worked perfectly.
Related
Consider the snippet:
#Controller
#RequestMapping(value = "/spitter")
public class SpittrController {
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegistrationForm() {
return "registerForm";
}
}
where registerForm.jsp is as simple as this:
<form method="post">
<table>
<tr>
<td>First Name:</td>
<td><input type="text" name="firstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input type="text" name="lastName" /></td>
</tr>
<tr>
<td>User Name:</td>
<td><input type="text" name="userName" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td><input type="submit" value="Register" /></td>
</tr>
</table>
</form>
Whn I type the following URL in my web browser:
http://localhost:8080/web/spitter/register
I see this below page, which is fine, as per the functionality:
Now if I slightly modified the URL, and do something like this
http://localhost:8080/web/spitter/register/
then also the same page is rendered,
Why? Even though the entered address(URL) is not pointing to that request mapped in the controller.
Any suggestions?
EDIT:
The whole problem arises when I have to work with Spring Security.
Consider the snippet:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and().authorizeRequests().antMatchers("/spitter/")
.authenticated().antMatchers(HttpMethod.GET, "/spitter/register")
.authenticated();
}
Now, when the user enters this in his browser,
http://localhost:8080/web/spitter/register
he is redirected to the login page to authenticate himself, while
http://localhost:8080/web/spitter/register/
doesn't redirects him to the login page, which is a security lapse.
and I have to make this entry to
antMatchers(HttpMethod.GET, "/spitter/register/").authenticated()
in addition to
antMatchers(HttpMethod.GET, "/spitter/register").authenticated()
Is there any cure of this to get rid of it or else it will double the effort just to append the / just to redirect to the login page?
Try this pattern
/spitter/register/**
It's possible to add HTML elements dynamically in a WebPart's CreateChildControls() method, like so:
protected override void CreateChildControls()
{
base.CreateChildControls();
. . .
HtmlGenericControl _breakingSpace = new HtmlGenericControl("br");
this.Controls.Add(_breakingSpace);
}
Is it possible to also add CSS rules programatically? For example, I want to make "labels" (LiteralControls) block elements so that their width value can be set. Is something like the following pseudocode possible?
CSSRule displayInlineBlock = new CSSRule("display: inline-block");
CSSRule width20em = new CSSRule("width: 20em");
reqDateStr.ApplyCSSRule(displayInlineBlock);
reqDateStr.ApplyCSSRule(width20em);
?
I've tried applying those CSS rules inline to the Literal Control itself like this:
LiteralControl reqDateStr = new LiteralControl("<span class=\"finaff-webform-field-label\" style=\"display: inline-block\"; width:200px\">Requester Date:</span>");
...but it doesn't work any differently than what I had before, which was:
LiteralControl reqDateStr = new LiteralControl("<span class=\"finaff-webform-field-label\">Requester Date:</span>");
You can see how the form looks here
UPDATE
In answer to ceej's inquiry as to what HTML is generated, here it is, straight from the browser's "Show Source" ("inline" is there, but seems to have no effect):
<h1>UCSC - Direct Payment Form</h1>
<table>
<tr>
<td colspan="4"><h2 class="finaff-webform-field-label">Section 1: Payment Information</h2></td>
<td colspan="2"><h2 class="finaff-webform-field-label">Section 2: Requester Information</h2></td>
</tr>
<tr>
<td><span class="finaff-webform-field-label" style="display: inline-block"; width:200px">Requester Date:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl11" type="text" value="4/23/2015" class="finaff-webform-field-input" /></td>
<td><span class="finaff-webform-field-label">Payment Amount:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl14" type="text" class="finaff-webform-field-input" /></td>
<td><span class="finaff-webform-field-label">Requester Name:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl17" type="text" class="finaff-webform-field-input" /></td>
</tr>
<tr>
<td><span class="finaff-webform-field-label">Payee Name:</span></td>
<td colspan="3"><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl21" type="text" size="64" class="finaff-webform-field-input" /></td>
<td><span class="finaff-webform-field-label">Dept / Div Name:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl24" type="text" class="finaff-webform-field-input" /></td>
</tr>
<tr>
<td><span class="finaff-webform-field-label">Remit Address:</span></td>
<td colspan="3"><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl28" type="text" size="64" class="finaff-webform-field-input" /></td>
<td><span class="finaff-webform-field-label">Phone:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl31" type="text" class="finaff-webform-field-input" /></td>
</tr>
<tr height="2em">
<td><span class="finaff-webform-field-label"> OR</span></td>
</tr>
<tr>
<td><span class="finaff-webform-field-label">Mail Stop:</span></td>
<td colspan="3"><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl37" type="text" size="64" class="finaff-webform-field-input" /></td>
<td><span class="finaff-webform-field-label">Email:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl40" type="text" class="finaff-webform-field-input" /></td>
</tr>
<tr>
<td><span class="finaff-webform-field-label">Last 4 Digits SSN or ITIN:</span></td>
<td><input name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl44" type="text" class="finaff-webform-field-input" /></td>
</tr>
<tr>
<td colspan="5"><input id="ctl00_ctl24_g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c_ctl47" type="checkbox" name="ctl00$ctl24$g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c$ctl47" /><label for="ctl00_ctl24_g_5f7ce2fb_5653_4cc9_b9b8_b00ee0d0910c_ctl47"><span class="finaff-webform-field-label">204 submitted or on file. <strong>NOTE:</strong> If not on file, complete a Payee_Setup_204</span></label></td>
</tr>
</table>
This should be possible. What is the generated HTML that is produced? Is the in-line style actually being output? Is the HTML malformed?
I think it might be as simple as having incorrectly specified the style in your line that applies the styles inline in the constructor of the LiteralControl. You are closing the style after inline-block - should this not be `style=\"display: inline-block; width:200px\? This would make the complete line
LiteralControl reqDateStr = new LiteralControl("<span class=\"finaff-webform-field-label\" style=\"display: inline-block; width:200px\">Requester Date:</span>");
You can certainly add dynamic controls within a web part and it should be done in the CreateChildControls method. Personally I would use a LiteralControl rather than an HtmlGenericControl for putting static text or mark up such as <br> on the page.
As for CSS and styling - most web controls have a CssClass property and a Style property. However, the control you have chosen (LiteralControl) does not. Have you considered using a Label control? This will generate a <span> and you can set the Style property. You would have something like
var reqDateStr = new Label
{
CssClass= "finaff-webform-field-label",
Text = "Requester Date:"
};
reqDateStr.Style.Add("display", "inline-block");
reqDateStr.Style.Add("width", "200px");
this.Controls.Add(reqDateStr);
You can even set an AssociatedControlId property, which will result in a <label for="textboxId"> being output. The value should be the Id of the input control, e.g. your text box. This might be desirable in your scenario.
Hope this helps...
I have a simple password reset dialog, which enables users to set a custom password.
<form id="resetPassword"
action="XXXXX">
<fieldset><input type="hidden" name="userId" value="${user.id}" />
<table>
<tbody>
<tr>
<td><input id="resetCustomPassword" class="ui-widget" type="checkbox"></td>
<td><label>Set Custom Password</label></td>
</tr>
</tbody>
<tbody style="display: none;">
<tr>
<td><label for="newPassword"> New Password: </label></td>
<td><input id="newPassword" class="ui-widget" type="password"></td>
</tr>
<tr>
<td><label for="reTypeNewPassword"> Retype New Password: </label></td>
<td><input id="reTypeNewPassword" class="ui-widget" type="password"></td>
</tr>
</tbody>
Now, if a user checks for "Set Custom password", I dynamically show the new password fields. The problem is in my this label in the above form:
<td><label>Set Custom Password</label></td>
This gets dynamically adjusted to the RIGHT side, so it aligns with the new password fields.
How can I let my above label be static, and not adjust itself dynamically?
Thanks!
Try this:
<td align="left"><label>Set Custom Password</label></td>
You're far better off using styled unordered lists as containers for forms, rather than tables.
See: http://www.alistapart.com/articles/multicolumnlists
I have used MVC MVC 2.0 Client Side validation, but it does not work as expected. Now I am trying to find out, what I did wrong.
How does it work?
I have this rendered form:
<form method="post" action="/Sprint/Edit/68d4886b-a86a-4f0b-b713-39219febddf3">
<fieldset>
<legend>Sprint</legend>
<table>
<tbody><tr>
<td><label for="sprint_Title">Title</label></td>
<td><input type="text" value="Wichtige Private Erledigungen" name="sprint.Title" id="sprint_Title" class="input-box t-input"></td>
<td><span class="error"><span id="sprint_Title_validationMessage" class="field-validation-valid"></span></span></td>
</tr>
<tr>
<td><label for="sprint_Date">Date</label></td>
<td>
<div id="sprint_Date" class="date-picker t-input t-widget t-datepicker"><input value="12.05.2010" name="sprint.Date" id="sprint_Date-input" class="t-input" autocomplete="off"><a title="Open the calendar" tabindex="-1" href="#" class="t-link t-icon t-icon-calendar">select date</a></div>
</td>
<td><span class="error"><span id="sprint_Date_validationMessage" class="field-validation-valid"></span></span></td>
</tr>
<tr>
<td><label for="sprint_Description">Description</label></td>
<td><textarea rows="10" name="sprint.Description" id="sprint_Description" cols="80" class="t-input">dsfs1</textarea></td>
<td><span class="error"><span id="sprint_Description_validationMessage" class="field-validation-valid"></span></span></td>
</tr>
</tbody></table>
</fieldset>
<input type="submit" value="Submit" name="Submit" id="Submit" class="t-button t-state-default">
</form>
And this script is rendered:
<script type="text/javascript">
//<![CDATA[
if (!window.mvcClientValidationMetadata) { window.mvcClientValidationMetadata = []; }
window.mvcClientValidationMetadata.push({"Fields":[{"FieldName":"sprint.Title","ReplaceValidationMessageContents":true,"ValidationMessageId":"sprint_Title_validationMessage","ValidationRules":[{"ErrorMessage":"Title is required.","ValidationParameters":{},"ValidationType":"required"}]},{"FieldName":"sprint.Date","ReplaceValidationMessageContents":true,"ValidationMessageId":"sprint_Date_validationMessage","ValidationRules":[{"ErrorMessage":"Das Feld \"Date\" ist erforderlich.","ValidationParameters":{},"ValidationType":"required"}]},{"FieldName":"sprint.Description","ReplaceValidationMessageContents":true,"ValidationMessageId":"sprint_Description_validationMessage","ValidationRules":[]}],"FormId":null,"ReplaceValidationSummary":false});
//]]>
</script>
But to my surprise the breakpoint only stops at page load. I think it should be also if a field is tabbed? At least, after I press the post button.
Why does client side validation not work for me?
This just sets up the handlers, it won't actually hit this line when the form is submitted, nor when you tab between fields.
You will get validation errors upon losing focus and/or form submission, however if you have other javascript errors on the page it can cause this to fail.
Also, make sure you've reference the required javascript files in your header:
MicrosoftAjax.js
MicrosoftMvcValidation.js
How do I access data from html in asp.net in the .cs (code behind) file?
In .aspx page I have:
<tr>
<td>Username:</td><td><input id="username" type="text" /></td>
</tr>
<tr>
<td>Password:</td><td><input id="password" type="password" /></td>
</tr>
<tr>
I know I can convert this to something like:
<tr>
<td>Username:</td><td><asp:TextBox ID="username" TextMode="SingleLine" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td>Password:</td><td><asp:TextBox ID="password" TextMode="Password" runat=server></asp:TextBox></td>
</tr>
This will allow me to access the controls via IDs.
However I was wondering if there was a way of accessing data without using asp.net server-side controls.
Give the inputs a name as well as an id and you will be able to get the values from Request.Form. Inputs without names are not sent back with the form post.
<input id="username" name="username" type="text" />
<input id="password" name="password" type="password" />
var username = Request.Form["username"];
var password = Request.Form["password"];
Add runat="server" to the controls, and then you can access them from the code-behind almost as if they were <asp:______ /> controls.
ASP.NET controls, are in essence HTML controls wrapped, so an asp:Button will render as a input Html control.
Some web developers prefer using Html controls due to the smaller size.
Therefore each HTML control will map to a asp server control.
As the previous answer, from Joel, add the runat="server", then the control can be referenced by the ID from the code behind.
This is your code:
<tr>
<td>Username:</td>
<td><input id="username" type="text" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input id="password" type="password" /></td>
</tr>
You can just add the runat="server" attribute to the Html controls:
<tr>
<td>Username:</td>
<td><input id="username" runat="server" type="text" /> <!--NOTE THE RUNAT="SERVER"--></td>
</tr>
<tr>
<td>Password:</td>
<td><input id="password" **runat="server"** type="password" /></td>
</tr>
Now you can access the controls in asp.net.