ASP.NET MVC View Messages - asp.net-mvc

I am using FluentValidation to validate my models, and it works awesome.
One question I have though is how do you handle messages that are not attached to a property?
Example: A customer login view. When the login is invalid I want to display a simple message.
What I did was add a property to the model, Message, and then created a validation message for that property on the view.
It works, but was looking to see what others are doing.
Update
So for simplicity, consider the following:
View Model
'Uses a FluentValidation Validator
Public Class LogonViewModel
Public Property UserName AS String<br>
Public Property Password AS String
End Class
View
<div id="GenericMessage">--Generic Messages Go Here--</div>
#<table border="0" cellpadding="2" cellspacing="0">
<tr>
<td>User Name:</td>
<td>#Html.EditorFor(Function(x) x.UserName) #Html.ValidationMessageFor(Function(x) x.UserName)</td>
</tr>
<tr>
<td>Password:</td>
<td>#Html.EditorFor(Function(x) x.Password) #Html.ValidationMessageFor(Function(x) x.Password)</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Logon" /></td>
</tr>
</table>
What I want to do is have a generic message div that I can display messages in, like "Invalid Login". My question is where to I put that in the model? Do I create a property and then set it in the controller ModelState? Or should I be using ViewData?

Any reason you aren't using the ModelState for your errors?
For example, if your view model has a datetime property and a user enters something like "blah", the ModelState will automatically have that error returned when you render the view again.
That error can be retrieved in the Validation Summary...
<%: Html.ValidationSummary() %>
Or you can bind it to specific form elements.
<%: Html.ValidationMessageFor(m => m.Birthdate) %>
You can also manually add error messages to the ModelState in your controller.
// for a specific property
ModelState.AddModelError("Birthdate", "You can't use this date!")
// to show in summary
ModelState.AddModelError("", "Dates are too close!")
If you are just after a way to communicate things from your controller to your view (other than errors), then I think it's fine to add a property to your viewModel, assign it a value in your controller, and then access it in your view.
And I don't see anything wrong with doing this for errors if ModelState isn't meeting your needs.

One question I have though is how do you handle messages that are not attached to a property?
As far as I understood from that question is you do not give any hint to framework to validate the input. right? if so, do it that way.
put the following code on your view;
#Html.ValidationSummary()
and validate your input inside the post action method. if it is not valid, add the error message to view state. here is an example;
if (captchaValid == false) {
ModelState.AddModelError("recaptcha", "Invalid characters on securty code! Please try it again");
return View(model);
}

Although I think I like better the Modelstate answers what I usually do is to define things like this in my _Layout.cshtml:
#if(TempData["Error"]!=null)
{
<div class="error">#TempData["Error"]</div>
}
#if(TempData["Warning"]!=null)
{
<div class="warning">#TempData["Warning"]</div>
}
then I only have to assign TempData["Error"] or TempData["Warning"] in my controller.

Related

Any reason why my ViewBag is not working?

I have following ActionResult in a controller and you can see that I set a message in the ViewBag if it's successful. Then on the View it should output that message if it's not empty. However, I can't get the message to display and I'm not seeing what the problem is.
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
{
Name = collection["RoleName"]
});
context.SaveChanges();
ViewBag.ResultMessage = "Role created successfully.";
return RedirectToAction("Index");
}
catch (Exception)
{
return View();
}
}
This is my Index.cshtml
#model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
#{
ViewBag.Title = "Index";
}
<h2>Roles Listing </h2>
#ViewBag.ResultMessage
#Html.ActionLink("Create New Role", "Create") | #Html.ActionLink("Manage User Role", "ManageUserRoles")
<div>
<table class="table table-bordered table-condensed table-striped table-hover ">
<thead>
<tr>
<th>Role</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var role in Model)
{
<tr>
<td><strong>#role.Name</strong></td>
<td>
<span onclick="return confirm('Are you sure you want to delete #role.Name?')">Delete</span> |
#Html.ActionLink("Edit", "Edit", new { roleName = #role.Name })
</td>
</tr>
}
</tbody>
</table>
</div>
ViewBag helps to maintain data when you move from controller to view. Short life means value becomes null when redirection occurs. This is because their goal is to provide a way to communicate between controllers and views. It’s a communication mechanism within the server call.
Since you are using RedirectToAction, the ViewBag becomes null when it reaches the view.
you can use TempData for this:
TempData["ResultMessage"] = "Role created successfully.";
It uses Session as storage, but it will not be around after the second response.
TempData helps to maintain data when you move from one controller to other controller or from one action to other action. In other words, when you redirect, Tempdata helps to maintain data between those redirects. It internally uses session variables. TempData use during the current and subsequent request only means it is used when you are sure that next request will be redirecting to next view.
For more understanding on this refer this link
The ViewBag property enables you to dynamically share values from the
controller to the view. (MSDN)
It’s life lies only during the current request, and if redirection occurs then it’s value becomes null.
And since you using RedirectToAction, which redirects to some different controller, value of ViewBag is lost.
Consider using TempData instead.
TempData["ResultMessage"] = "Role created successfully.";
(See this for usage)
The viewbag/viewdata scope is available for controller to view only. if you use tempdata, it will available one request , you can extend more than one request

Best way to display a search form and its results in the same page?

Suppose I have a simple search form with a textbox. And upon submitting the form I send the contents of the textbox to a stored procedure which returns to me the results. I want the results to be displayed on the same page the form was, except just below it.
Right now I'm doing the following but it's not working out exactly the way I want:
"Index" View of my SearchController
#using (Html.BeginForm("SearchResults", "Search", FormMethod.Post, new { #class = "searchform" }))`{
<fieldset>
<legend>Name</legend>
<div class="editor-label">
#Html.Label("Search")
</div>
<div class="editor-field">
#Html.TextBox("Name")
</div>
<input type="submit" value="Search" class="formbutton" />
</fieldset>
#{ Html.RenderPartial("SearchResults", null);
This is my "SearchResults" View:
#model IEnumerable<MyProject.Models.spSearchName_Result>
<table>
#foreach (var item in Model)
{
<tr>
<td>
#item.Name
</td>
</tr>
}
</table>
This is my Controller:
// GET: /Search/SearchResult
[HttpPost]
public ActionResult SearchResult(FormCollection collection)
{
var result = myentity.spSearchName(collection["Name"]);
return PartialView("SearchResults", result);
}
I can only seem to get the results to display on an entirely new page (not being embedded as a partial view), or I get an error when I load the search page because there are no results (since I hadn't searched yet).
Is there any better way to achieve what I'm trying to do? I feel like I'm going against some of the best practices in MVC.
You could return the results in a ViewData object then only show on the view it if is not null.
Very similar to this question MVC 3 form post and persisting model data
For this instance it looks like you are not passing the results to your partial view. Try this?
#{ Html.RenderPartial("SearchResults", Model.Results);
Since you are not persisting your search information using a model, the search information will be lost when the search form is posted.
Given your design and stated goal, it would be best to convert the form in your Index view into an Ajax form, then your controller can send your partial view back to populate a div below your Ajax form.
counsellorben

ASP.NET Collection Model Binding Nested Form Problem

I have a partial view that is bound to an object Cart. Cart has a collection of CartLines. My view is below:
<tbody>
<% foreach (var line in Model.Lines) { %>
<tr>
<td align="center"><%=Html.CatalogImage(line.Product.DefaultImage, 80) %></td>
<td align="left">
<%=Html.ActionLink(line.Product.Name, "Product", "Catalog",
new { productId = line.Product.Id }, new { title = "View " + line.Product.Name })%>
</td>
<td align="right"><%= line.Product.Price.ToString("c")%></td>
<td align="center">
<%=Html.Hidden("lines[" + i + "].key", line.Product.Id) %>
<%=Html.TextBox("lines[" + i + "].value", line.Quantity, new { #class = "quantity" })%>
</td>
<td align="right"><%= (line.LineTotal).ToString("c")%></td>
<td>
<%using (Ajax.BeginForm("RemoveFromCart", "Cart",
new {ProductId = line.Product.Id, returnUrl = ViewData["returnUrl"]},
new AjaxOptions { UpdateTargetId="cart", LoadingElementId="loading" }))
{%>
<input type="image" src="<%=AppHelper.ImageUrl("delete.gif")%>" value="Remove item" />
<%} %>
</td>
</tr>
<% i++; } %>
</tbody>
There are two things to note. The first is that I am using a form per line for removing items.
The second is that I had attempted to allow users to change the quantity of line items and then click an update button to pass all the changes to the controller action:
// POST: /Cart/Update
[HttpPost]
public ActionResult Update(Cart cart, IDictionary<int,int> lines, string returnUrl)
{
foreach (var line in lines) {
Product p = _catalogService.GetProduct(line.Key);
cart.UpdateItem(p, line.Value);
}
if (Request.IsAjaxRequest())
return PartialView("Cart", cart);
else
return RedirectToAction("Index", new { returnUrl });
}
Note that I am using a dictionary since I am only concerned about the product and quantity. I don't really like the fact that I am having to retrieve the product again before calling cart.UpdateItem but I couldn't figure out how to pass the Product from the model to my action instead of the id.
The main problem however, is rather stupidly I wrapped the entire cart in a form so that I could post back the values and then spent a good hour wondering why things were not working correctly in IE - doh! nested forms
So I am stuck on how to get round this. I want the ability to remove items individually but allow a user to change item quantities and then pass all changes at once to the controller. I can't use links for my remove action as I would need to use javascript to force a post and everything must work without javascript enabled.
[Update]
Would a better solution be to allow updates on my custom model binder? This way I could make changes inside my view and post the cart object back to the controller - although I'm not sure whether this is possible with child collections (Cart.CartItems).
I've had a look on sites like Amazon and it would appear they wrap the entire cart in a form and both global update buttons and indidivual remove item buttons post back to the same action when javascript is disabled.
Any help would be appreciated.
Thanks,
Ben
There is only one way here and thats the ugly way. Have 1 form around everything.
Then in the action you have to check which button was pressed (you get the name of the button in the request).
It gets even more ugly with differences in firefox and ie. If you have a button pressed ie or firefox (Dont remember which one) not only sends the name of the pressed button, but also the location where the button was pressed.
You have more options if your solution can rely on JS enabled browsers. But thats another story.

Checkbox HTML Helper

I've been working on an ASP.net MVC project that uses checkbox HTML Helpers in one of the views. The problem I'm trying to resolve is maintaining the checkbox state on a page refresh or when a user hits to he back button on their browser. I'm trying to use the HTML helper as a start, but I lack a complete understanding of how it works. I'm stuck on the third parameter that asks for HTML attributes. A snippet from a form that I have is as follows:
<tr>
<td><label for="Name">Name</label></td>
<td><%= Html.Encode(entity.CONTACT_NAME)%></td>
<td><input type="checkbox" name="Name" value="<%= Html.Encode(entity.CONTACT_NAME)%>"/> </td>
<td><%= Html.CheckBox("Name", false, new {#name = Html.Encode(entity.CONTACT_NAME)}) %></td>
</tr>
To avoid confusion, I have an object called entity that I declare before my form, that has several string values, one of which is CONTACT_NAME. I have a separate, standard, html checkbox right above the HTML Helper for testing purposes. When my form POSTs, I get the value if I select the standard checkbox, if I select the helper I get only true.
What I want to know is, how I can get
the value like I do when I select the
standard checkbox?
And how can I
maintain the checkbox state on page
refresh??
Any help is appreciated, thanks.
UPDATE:
#NickLarsen - Looked at the HTML code that was generated, the value is "false"
Made changes as per anthonyv's and JonoW's suggestions, my View is now as follows:
<tr>
<td><label for="Name">Name</label></td>
<td><%= Html.Encode(entity.CONTACT_NAME)%></td>
<td><%= Html.CheckBox("Name", false, new {#value = Html.Encode(entity.CONTACT_NAME)}) %></td>
</tr>
But the generated HTMl still shows the value as a boolean "false" instead of the actual CONTACT_NAME.
As per NickLarsen's suggestion, here is the code in my controller that checks the values.
public ActionResult ProcessRequest(Request request, FormCollection form)
{
var aChangeRequest = new ChangeRequest();
TryUpdateModel(aChangeRequest, new string[] { "Name" },form.ToValueProvider());
//Way more follows
}
should "#name" be "#value"? It looks like you are trying to set the name twice...
I'm pretty sure you want to have the following:
<%= Html.CheckBox("Name", false, new {#value = Html.Encode(entity.CONTACT_NAME)}) %>
If you have 2 inputs with the same name, they will be posted as a list of values (which MVC is going to try convert to a boolean value). So it's probably going to distort your test by having 2 elements with the same name, would suggest changing one of the names.

How to handle checkboxes in ASP.NET MVC forms?

Caution: This question is over nine years old!
Your best option is to search for newer questions, or to search the answers below looking for your specific version of MVC, as many answers here are obsolete now.
If you do find an answer that works for your version, please make sure the answer contains the version of MVC you are using.
(The original question starts below)
This seems a bit bizarre to me, but as far as I can tell, this is how you do it.
I have a collection of objects, and I want users to select one or more of them. This says to me "form with checkboxes." My objects don't have any concept of "selected" (they're rudimentary POCO's formed by deserializing a wcf call). So, I do the following:
public class SampleObject{
public Guid Id {get;set;}
public string Name {get;set;}
}
In the view:
<%
using (Html.BeginForm())
{
%>
<%foreach (var o in ViewData.Model) {%>
<%=Html.CheckBox(o.Id)%> <%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
And, in the controller, this is the only way I can see to figure out what objects the user checked:
public ActionResult ThisLooksWeird(FormCollection result)
{
var winnars = from x in result.AllKeys
where result[x] != "false"
select x;
// yadda
}
Its freaky in the first place, and secondly, for those items the user checked, the FormCollection lists its value as "true false" rather than just true.
Obviously, I'm missing something. I think this is built with the idea in mind that the objects in the collection that are acted upon within the html form are updated using UpdateModel() or through a ModelBinder.
But my objects aren't set up for this; does that mean that this is the only way? Is there another way to do it?
Html.CheckBox is doing something weird - if you view source on the resulting page, you'll see there's an <input type="hidden" /> being generated alongside each checkbox, which explains the "true false" values you're seeing for each form element.
Try this, which definitely works on ASP.NET MVC Beta because I've just tried it.
Put this in the view instead of using Html.CheckBox():
<% using (Html.BeginForm("ShowData", "Home")) { %>
<% foreach (var o in ViewData.Model) { %>
<input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
<%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
Your checkboxes are all called selectedObjects, and the value of each checkbox is the GUID of the corresponding object.
Then post to the following controller action (or something similar that does something useful instead of Response.Write())
public ActionResult ShowData(Guid[] selectedObjects) {
foreach (Guid guid in selectedObjects) {
Response.Write(guid.ToString());
}
Response.End();
return (new EmptyResult());
}
This example will just write the GUIDs of the boxes you checked; ASP.NET MVC maps the GUID values of the selected checkboxes into the Guid[] selectedObjects parameter for you, and even parses the strings from the Request.Form collection into instantied GUID objects, which I think is rather nice.
HtmlHelper adds an hidden input to notify the controller about Unchecked status.
So to have the correct checked status:
bool bChecked = form[key].Contains("true");
In case you're wondering WHY they put a hidden field in with the same name as the checkbox the reason is as follows :
Comment from the sourcecode MVCBetaSource\MVC\src\MvcFutures\Mvc\ButtonsAndLinkExtensions.cs
Render an additional <input
type="hidden".../> for checkboxes.
This addresses scenarios where
unchecked checkboxes are not sent in
the request. Sending a hidden input
makes it possible to know that the
checkbox was present on the page when
the request was submitted.
I guess behind the scenes they need to know this for binding to parameters on the controller action methods. You could then have a tri-state boolean I suppose (bound to a nullable bool parameter). I've not tried it but I'm hoping thats what they did.
You should also use <label for="checkbox1">Checkbox 1</label> because then people can click on the label text as well as the checkbox itself. Its also easier to style and at least in IE it will be highlighted when you tab through the page's controls.
<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>
This is not just a 'oh I could do it' thing. Its a significant user experience enhancement. Even if not all users know they can click on the label many will.
I'm surprised none of these answers used the built in MVC features for this.
I wrote a blog post about this here, which even actually links the labels to the checkbox. I used the EditorTemplate folder to accomplish this in a clean and modular way.
You will simply end up with a new file in the EditorTemplate folder that looks like this:
#model SampleObject
#Html.CheckBoxFor(m => m.IsChecked)
#Html.HiddenFor(m => m.Id)
#Html.LabelFor(m => m.IsChecked, Model.Id)
in your actual view, there will be no need to loop this, simply 1 line of code:
#Html.EditorFor(x => ViewData.Model)
Visit my blog post for more details.
Here's what I've been doing.
View:
<input type="checkbox" name="applyChanges" />
Controller:
var checkBox = Request.Form["applyChanges"];
if (checkBox == "on")
{
...
}
I found the Html.* helper methods not so useful in some cases, and that I was better off doing it in plain old HTML. This being one of them, the other one that comes to mind is radio buttons.
Edit: this is on Preview 5, obviously YMMV between versions.
They appear to be opting to read the first value only, so this is "true" when the checkbox is checked, and "false" when only the hidden value is included. This is easily fetched with code like this:
model.Property = collection["ElementId"].ToLower().StartsWith("true");
#Dylan Beattie Great Find!!! I Thank you much. To expand even further, this technique also works perfect with the View Model approach. MVC is so cool, it's smart enough to bind an array of Guids to a property by the same name of the Model object bound to the View. Example:
ViewModel:
public class SampleViewModel
{
public IList<SampleObject> SampleObjectList { get; set; }
public Guid[] SelectedObjectIds { get; set; }
public class SampleObject
{
public Guid Id { get; set; }
public string Name { get; set; }
}
}
View:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
<thead>
<tr>
<th>Checked</th>
<th>Object Name</th>
</tr>
</thead>
<% using (Html.BeginForm()) %>
<%{%>
<tbody>
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
</tbody>
</table>
<input type="submit" value="Submit" />
<%}%>
Controller:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SampleView(Guid id)
{
//Object to pass any input objects to the View Model Builder
BuilderIO viewModelBuilderInput = new BuilderIO();
//The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);
return View("SampleView", viewModel);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SampleView(SampleViewModel viewModel)
{
// The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
return View();
}
Anyone familiar with the View Model philosophy will rejoice, this works like a Champ!
I'd also like to point out that you can name each checkbox a different name, and have that name part of the actionresults parameters.
Example,
View:
<%= Html.CheckBox("Rs232CheckBox", false, new { #id = "rs232" })%>RS-232
<%= Html.CheckBox("Rs422CheckBox", false, new { #id = "rs422" })%>RS-422
Controller:
public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
...
}
The values from the view are passed to the action since the names are the same.
I know this solution isn't ideal for your project, but I thought I'd throw the idea out there.
<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>
From the Controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection fc)
{
var s = fc["checkbox1"];
if (s == "on")
{
string x = "Hi";
}
}
This issue is happening in the release 1.0 as well. Html.Checkbox() causes another hidden field to be added with the same name/id as of your original checkbox. And as I was trying loading up a checkbox array using document.GetElemtentsByName(), you can guess how things were getting messed up. It's a bizarre.
From what I can gather, the model doesn't want to guess whether checked = true or false, I got around this by setting a value attribute on the checkbox element with jQuery before submitting the form like this:
$('input[type="checkbox"]').each(function () {
$(this).attr('value', $(this).is(':checked'));
});
This way, you don't need a hidden element just to store the value of the checkbox.
I know that this question was written when MVC3 wasn't out, but for anyone who comes to this question and are using MVC3, you may want the "correct" way to do this.
While I think that doing the whole
Contains("true");
thing is great and clean, and works on all MVC versions, the problem is that it doesn't take culture into account (as if it really matters in the case of a bool).
The "correct" way to figure out the value of a bool, at least in MVC3, is to use the ValueProvider.
var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));
I do this in one of my client's sites when I edit permissions:
var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();
foreach (var key in allPermissionsBase)
{
// Try to parse the key as int
int keyAsInt;
int.TryParse(key.Replace("permission_", ""), out keyAsInt);
// Try to get the value as bool
var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}
Now, the beauty of this is you can use this with just about any simple type, and it will even be correct based on the Culture (think money, decimals, etc).
The ValueProvider is what is used when you form your Actions like this:
public ActionResult UpdatePermissions(bool permission_1, bool permission_2)
but when you are trying to dynamically build these lists and check the values, you will never know the Id at compile time, so you have to process them on the fly.
The easiest way to do is so...
You set the name and value.
<input type="checkbox" name="selectedProducts" value="#item.ProductId" />#item.Name
Then on submitting grab the values of checkboxes and save in an int array.
then the appropriate LinQ Function. That's it..
[HttpPost]
public ActionResult Checkbox(int[] selectedObjects)
{
var selected = from x in selectedObjects
from y in db
where y.ObjectId == x
select y;
return View(selected);
}
Same as nautic20's answer, just simply use MVC default model binding checkbox list with same name as a collection property of string/int/enum in ViewModel. That is it.
But one issue need to point out. In each checkbox component, you should not put "Id" in it which will affect MVC model binding.
Following code will work for model binding:
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
Following codes will not binding to model (difference here is it assigned id for each checkbox)
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
this is what i did to loose the double values when using the Html.CheckBox(...
Replace("true,false","true").Split(',')
with 4 boxes checked, unchecked, unchecked, checked it turns
true,false,false,false,true,false
into
true,false,false,true.
just what i needed
How about something like this?
bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
ModelState.AddModelError(”chkHuman”, “Nice try.”);
When using the checkbox HtmlHelper, I much prefer to work with the posted checkbox form data as an array. I don't really know why, I know the other methods work, but I think I just prefer to treat comma separated strings as an array as much as possible.
So doing a 'checked' or true test would be:
//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true");
Doing a false check would be:
//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true");
The main difference is to use GetValues as this returns as an array.
Just do this on $(document).ready :
$('input:hidden').each(function(el) {
var that = $(this)[0];
if(that.id.length < 1 ) {
console.log(that.id);
that.parentElement.removeChild(that);
}
});
My solution is:
<input type="checkbox" id="IsNew-checkbox" checked="checked" />
<input type="hidden" id="IsNew" name="IsNew" value="true" />
<script language="javascript" type="text/javascript" >
$('#IsNew-checkbox').click(function () {
if ($('#IsNew-checkbox').is(':checked')) {
$('#IsNew').val('true');
} else {
$('#IsNew').val('false');
}
});
</script>
More you can find here:
http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a-valid-boolean/
I had nearly the same Problem but the return Value of my Controller was blocked with other Values.
Found a simple Solution but it seems a bit rough.
Try to type Viewbag. in your Controller and now you give it a name like Viewbag.Checkbool
Now switch to the View and try this #Viewbag.Checkbool with this you will get the value out of the Controller.
My Controller Parameters look like this:
public ActionResult Anzeigen(int productid = 90, bool islive = true)
and my Checkbox will update like this:
<input id="isLive" type="checkbox" checked="#ViewBag.Value" ONCLICK="window.location.href = '/MixCategory/Anzeigen?isLive=' + isLive.checked.toString()" />
Using #mmacaulay , I came up with this for bool:
// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");
If checked
active = true
If unchecked
active = false

Resources