Jquery Mobile check box value invalid in MVC3 view model - asp.net-mvc-3

I'm learning Jquery Mobile. I'm trying to set up the logon page for my .NET MVC3 site. My controller is just the standard MVC3 account controller.
Here is my Jquery Mobile page:
<html>
<head>
<title>Mobile Logon</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0-alpha.1/jquery.mobile-1.2.0-alpha.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(document).bind("mobileinit", function(){
$.extend( $.mobile , {
ajaxEnabled: false
});
});
</script>
<script src="http://code.jquery.com/mobile/1.2.0-alpha.1/jquery.mobile-1.2.0-alpha.1.min.js"></script>
</head>
<body>
<div data-role="page" data-theme="e">
<div data-role="header">
<a href="#Url.Action("Index", "Home")" data-icon="arrow-l" rel="external" >Back</a>
<h1>Logon</h1>
</div>
<div data-role = "content">
#Html.ValidationSummary(true, "Login was unsuccessful.")
#using (Html.BeginForm("Logon", "Account", FormMethod.Post, null))
{
<label for="Username">User Name (e-mail address)</label><input type="email" name="Username" />
<label for="Password">Password</label><input type="password" name="Password" />
<label><input type="checkbox" name="RememberMe" data-theme="c" />Remember Me</label>
<button type="submit" value="Log On"></button>
}
<center>or</center>
#using(Html.BeginForm("Register", "Account", FormMethod.Get, null ))
{
<button type="submit" value="Register for an account" data-transition="flip"></button>
}
</div>
</div>
When I test the page, if I leave the "Remember Me" box unchecked, then everything works fine. However, if I check the box and click "Log On", then the controller says that the model is invalid. As I step through the code, I notice that it also thinks that the value for "RememberMe" is false whether the box is checked or not.
Here is the view model for the logon page
public class LogOnModel
{
[Required]
[Display(Name = "E-mail address")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}

You can use your extra mobile attributes when using the HtmlHelpers, an example is below:
#Html.TextBoxFor(x => x.UserName, new { type = "email" })
#Html.CheckBoxFor(x => x.RememberMe, new { data_theme = "c" })
MVC 3 converts underscores in attribute names to dashes, so your data-theme attribute remains in-tact. I have just tested this and it works perfectly for your needs.

Related

How pass extra param from html to controller

Spring Boot 2.5, Thymeleaf
I need when click submit to pass object Product and additional extra param (quantity)
html template:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${appName}">Category template title</title>
<link th:href="#{/public/style.css}" rel="stylesheet"/>
<meta charset="UTF-8"/>
</head>
<body>
<div class="container">
<h3 th:text="*{title}"/>
<form method="post" action="#" th:object="${product}" th:action="#{/product}">
<input type="hidden" id="id" th:field="*{id}"/>
<input type="text" placeholder="Name" id="name" th:field="*{name}" th:disabled="${isView}"/>
<input type="hidden" id="created" th:field="*{created}"/>
<textarea placeholder="Description" rows="5" id="description"
th:field="*{description}" th:disabled="${isView}"></textarea>
<input type="number" placeholder="Price" id="price" th:field="*{price}" th:disabled="${isView}"/>
<input type="text" placeholder="Currency" id="currency" th:field="*{currency}" th:disabled="${isView}"/>
<input type="text" placeholder="Images URL(separate by comma)" id="images" th:field="*{images}" th:disabled="${isView}"/>
<input th:type="${isView} ? hidden : submit" value="Submit"/>
</form>
</div>
</body>
</html>
and here my controller:
#RequestMapping("cart/add")
public String addProduct(Model model) {
logger.info("addProduct");
model.addAttribute("isAdd", true);
model.addAttribute("product", new Product());
model.addAttribute("title", "Add Product");
model.addAttribute("viewMode", ViewMode.ADD);
return "product";
}
#PostMapping(value = "/product")
public String submitProduct(Product product, Model model) {
logger.info("submitProduct = " + product);
if (product.getId() == 0) { // add category
product.setCreated(new Date());
} else { // update category
product.setUpdated(new Date());
}
return "redirect:/cart";
}
So when click button Submit call submitProduct with fill object Product. But I need to pass extra param (as second param in method submitProduct) - quantity.
How I can pass this extra int param from html to controller?
One option is to access the value directly from the request parameters.
Assuming the quantity value is available in the form as an input field, with a name of quantity (looks like it is not there at the moment), then you can alter your controller to use this:
import org.springframework.web.bind.annotation.RequestParam;
And then change the relevant method signature to something like this:
public String submitProduct(Product product, Model model,
#RequestParam(name = "quantity") String quantity) {...}
(Field validation of some kind would also be needed, I assume.)

MVC3 Remote Validation of a field within an IEnumerable

I have an object inside an IEnumerable of my model class, the rendered HTML looks like
<input data-val="true" data-val-number="The field money must be a number." data-val-remote="&#39;money&#39; is invalid." data-val-remote-additionalfields="*.money" data-val-remote-url="/RemoteValidator/ValidateMoney" data-val-required="The money field is required." id="BudgetDetails_0__BudgetData_Money" name="BudgetDetails[0].BudgetData.Money" type="text" value="100" />
<span class="field-validation-valid" data-valmsg-for="BudgetDetails[0].BudgetData.Money" data-valmsg-replace="true"></span>
The model classes look like
public class MyViewModel
{
public IEnumerable<Budget> BudgetDetails { get; set; }
}
public class Budget
{
public int SomeIdentifier { get; set; }
public BudgetValues BudgetData { get; set; }
}
public class BudgetValues
{
[Remote("ValidateMoney", "RemoteValidator")]
public decimal? Money { get; set; }
// other properties
}
View is
#model DictionaryAndRemote.Models.MyViewModel
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script src="#Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
</head>
<body>
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.BudgetDetails)
<br />
<input type="submit" value="Submit user Data" />
}
</body>
</html>
The edit template Views\Shared\EditorTemplates\Budget.cshtml is
#model DictionaryAndRemote.Models.Budget
<div id="#Model.SomeIdentifier.ToString()">
<div>
#Html.TextBoxFor(x => x.BudgetData.Money)
#Html.ValidationMessageFor(x => x.BudgetData.Money)
</div>
</div>
The UI will trigger Ajax call http://localhost:4276/RemoteValidator/ValidateMoney?BudgetDetails%5B0%5D.BudgetData.Money=500 but unfortunately routing table is unable to match the request to my action method
public ActionResult ValidateMoney(decimal money)
{
return Json("I will always fail you.", JsonRequestBehavior.AllowGet);
}
Because the parameter name does not match. Since is is inside an IEnumerable the parameter name is even dynamic BudgetDetails[0].BudgetData.Money, BudgetDetails[1].BudgetData.Moneyand so on.
Of course I always can tweak action medhod to be
public ActionResult ValidateMoney()
{
string parameter = Request.QueryString.ToString();
return Json("I will always fail you.", JsonRequestBehavior.AllowGet);
}
And use very primitive way to parse query string, but I don't think it is the most elegant solution.
Anybody has some experience to share?
Try this way.
public JsonResult ValidateMoney([Bind(Include = "Money")]BudgetValues budgetValues)
{
if(null != budgetValues)
{
decimal money = budgetValues.Money
}
return Json("I will always fail you.", JsonRequestBehavior.AllowGet);
}

ASP.NET MVC validation problem - data is not posted

I have the following class:
public class NewCommentClass
{
public string ActionName { get; set; }
public object RouteValues { get; set; }
[Required(ErrorMessage = "Comment Required")]
public string Comment { get; set; }
public int? CommentParentID { get; set; }
}
following code in view:
NewCommentClass newCommentClass = new NewCommentClass() { ActionName = "PostComment", RouteValues = new { id = ideaItem.Ideas.IdeaID } };
Html.RenderPartial("~/Views/Shared/NewComment.ascx", newCommentClass);
and NewComment.ascx:
<% # Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NEOGOV_Ideas.Models.NewCommentClass>" %>
....
<div class="comment-new-container">
<div class="grid_1 alpha item-sidebar">
<p style="padding-top: 0.5em">
<a href="#">
<img src="<% = userAvatar %>" class="profile-photo" alt="Your Profile Picture" width="48"
height="48" /></a>
</p>
</div>
<div class="grid_8 omega">
<div class="comment-body">
<% using (Html.BeginForm(Model.ActionName, "Home", Model.RouteValues, FormMethod.Post, new { id = "FormAddComment", name = "FormAddComment" }))
{ %>
<fieldset>
<% = Html.TextAreaFor(model => model.Comment, htmlAttributes)%>
<% = Html.ValidationMessageFor(model=>model.Comment) %>
<input type="submit" value="<% = postButtonTitle %>" class="small blue awesome noborder" />
</fieldset>
<%} %>
</div>
</div>
<div class="clear">
</div>
</div>
and following post method in controller:
public ActionResult PostComment(int id, string Comment, int? CommentParentID, string referrerUrl)
{
...
}
but this validation does not work correctly.
If I enter data to textarea and click on "Submit" - all ok
But If I just click on "Submit" without data inside - got error message (it's correct), but when I enter data to textarea after this action - error message is hidden, but form is not submited!. If I add Html.ValidationSummary(true) - I one label is hidden, but second is shown.
Why so strange behaviour?
In your Html.BeginForm() command, you create an HtmlAttribute object, and you use it to set the name and id of your textarea to FormAddComment. Because this is the only field in the form, you would need to change your method signature as follows:
[HttpPost]
public ActionResult PostComment(string FormAddComment)
Your current signature doesn't receive anything from the posted form. If you use Fiddler or a similar tool to inspect what is being posted, you will see FormAddComment=[whatever was typed into the textarea] as the body of the POST sent from your browser.

MVC3/Razor Client Validation Not firing

I am trying to get client validation working in MVC3 using data annotations. I have looked at similar posts including this MVC3 Client side validation not working for the answer.
I'm using an EF data model. I created a partial class like this for my validations.
[MetadataType(typeof(Post_Validation))]
public partial class Post
{
}
public class Post_Validation
{
[Required(ErrorMessage = "Title is required")]
[StringLength(5, ErrorMessage = "Title may not be longer than 5 characters")]
public string Title { get; set; }
[Required(ErrorMessage = "Text is required")]
[DataType(DataType.MultilineText)]
public string Text { get; set; }
[Required(ErrorMessage = "Publish Date is required")]
[DataType(DataType.DateTime)]
public DateTime PublishDate { get; set; }
}
My cshtml page includes the following.
<h2>Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Post</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Text)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Text)
#Html.ValidationMessageFor(model => model.Text)
</div>
}
Web Config:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
Layout:
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
So, the Multiline Text annotation works and creates a text area. But none of the validations work client side. I don't know what i might be missing. Any ideas?? i can post more information if needed. Thanks!
1.)
Try adding the following into the view which you are validating
HtmlHelper.ClientValidationEnabled = true;
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
I did not find it necessary to modify Web.config, so you may remove
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
Good luck! Also, try putting in a known bad value to see if client side validation is triggered, the required annotation does not seem to be enough to display a message for a blank input.
2.)
Put below scripts in your view, it should work.
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Try to declare using public object :
public class Post_Validation
{
[Required(ErrorMessage = "Title is required")]
[StringLength(5, ErrorMessage = "Title may not be longer than 5 characters")]
public object Title { get; set; }
[Required(ErrorMessage = "Text is required")]
[DataType(DataType.MultilineText)]
public object Text { get; set; }
[Required(ErrorMessage = "Publish Date is required")]
[DataType(DataType.DateTime)]
public object PublishDate { get; set; }
}

MVC 2 Client and Server Validation with Data Annotations - Required not working

I have a Create view which is passed a ViewModel. The ViewModel contains the following:
namespace MyProject.ViewModels
{
public class MyObjectCreateView
{
public MyObject MyObject { get; set; }
public List<OtherObject> OtherObjects { get; set; }
}
}
The objects are generated using Entity Framework. I have a metadata partial class for MyObject:
[MetadataType(typeof(MyObjectMetaData))]
public partial class MyObject
{
// Validation rules for the MyObject class
public class MyObjectMetaData
{
// Validation rules for MyObjectId
[DisplayName("MyObject")]
[Required(ErrorMessage = "Please enter the MyObject ID number.")]
[DisplayFormat( ApplyFormatInEditMode=true,
ConvertEmptyStringToNull=true,
HtmlEncode=true)]
[DataType(DataType.Text)]
[StringLength(25, ErrorMessage = "Must be under 25 characters.")]
public object MyObjectId { get; set; }
// Validation rules for Title
[Required(ErrorMessage = "Please enter the Title for MyObject.")]
[DataType(DataType.MultilineText)]
[StringLength(200, ErrorMessage = "Must be under 200 characters.")]
[DisplayFormat(ApplyFormatInEditMode = true,
ConvertEmptyStringToNull = true,
HtmlEncode = true)]
public object Title { get; set; }
Etc...
My Create view looks like this:
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) {%>
<%:Html.ValidationSummary(true, "Please fix the following errors:") %>
<%:Html.EditorFor(model => model.MyObject) %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
<div>
<%:Html.ActionLink("Back to List", "Index") %>
</div>
Finally, the editor for MyObject:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<TxRP.Models.MyObject>" %>
<%--EditorTemplate--%>
<fieldset>
<div class="editor-label"><%:Html.LabelFor(model => model.MyObjectId)%></div>
<div class="editor-field">
<%:Html.TextBoxFor(model => model.MyObjectId)%>
<%= Html.ValidationMessageFor(model => model.MyObjectId) %>
</div>
<div class="editor-label"><%:Html.LabelFor(model => model.Title)%></div>
<div class="editor-field">
<%:Html.TextAreaFor(model => model.Title, new { cols = "80" })%>
<%= Html.ValidationMessageFor(model => model.Title)%>
</div>
I have Client validation set, and all the scripts are in the master page:
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcJQueryValidation.js" type="text/javascript"></script>
<script src="../../scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="../../Scripts/ui/minified/jquery.ui.core.min.js" type="text/javascript"></script>
<script src="../../Scripts/ui/minified/jquery.ui.datepicker.min.js" type="text/javascript"></script>
<link href="../../Content/Site.css" type="text/css" rel="Stylesheet" />
<link href="../../Content/jquery-ui/sunny/jquery-ui-1.8.4.custom.css" type="text/css" rel="Stylesheet" />
When I click the Save button, no validation happens. No client validation, no server validation (it doesn't even seem to hit the Post create action at all!); it just bombs on the entity framework model with a ConstraintException, because Title is null. Argh!
I'm sure it's just some silly thing I've overlooked, but I know I had it working at one point, and now it's not, and I've been trying to figure this out all week. Thanks for any help, I'm developing a callous on my forehead from banging it on my desk!
EDIT: Here is the controller:
public ActionResult Create(MyObject myObject)
{
if (!ModelState.IsValid)
{
//ModelState is invalid
return View(new MyObject());
}
try
{
//TODO: Save MyObject
return RedirectToAction("Index");
}
catch
{
//Invalid - redisplay with errors
return View(new MyObject());
}
}
and the exception stack trace:
at System.Data.Objects.DataClasses.StructuralObject.SetValidValue(String value, Boolean isNullable)
at MyProject.Models.MyObject.set_Title(String value) in C:\CodeProjects\MyProject\Models\MyProjectDB.Designer.cs:line 4941
Couple of remarks about your code:
You say that you have a view model but what I see looks more like an Entity Framework autogenerated model. Properties of type object, ... arghhh...
You include both MicrosoftMvcValidation.js and MicrosoftMvcJQueryValidation.js but those are mutually exclusive. You have to decide whether you will do client validation using MS Technology or jquery validate plugin.
You didn't show any code of the controller actions nor the exact exception stack trace you are getting. You are saying that the Post action is not hit but you get an exception. Where do you get this exception?

Resources