About binding a checkbox to string property in MVC viewmodel - asp.net-mvc

In my project I have a string field in the view model to display in a form and post back to the controller.
However for some reason, I'd like to display a checkbox, and retrieving string "True"/"False" from user input
I've searched through the internet and found this
How to render a model property of string type as checkbox in ASP.NET MVC
which leverage the editor template and achieve my need.
My question is that how do this be achieved, because in the editor template, I can only see it how to interpret the string to a checkbox, but it never explain or show how the checkbox value will be bind back to the string field with "True"/"False".
What should I do if I wanted "Yes"/"No" instead of "true"/"false", are there any converter that I need to make to parsing the checkbox to string?
Sorry for my bad English and lack of mvc knowledge, I just started MVC and web development for a few days.
UPDATE:
1. I am using ViewModel to bind with the forms, so I need something like Html.CheckBoxFor(x=>x.value)
while x.value is a string, obviously it is not possible with the default CheckboxFor

I think what you are asking is how to save the value back into your database, which is more of a back-end C# or VB question.
As you know, when you submit a form on an HTML page, if a checkbox is ticked, it's value will be passed in the POST parameters back to the server:
front-end HTML:
<input type="checkbox" name="theCheckBox" value="Yes" />
back-end C# in Page_Load() or similar
if(Request.Form["theCheckBox"] == "Yes") {
// save value "Yes" into database
}
just remember that if the checkbox is NOT TICKED, Request.Form["theCheckBox"] will be null

Related

MVC html string field 2 way binding

I have a controller that have a field HtmlContents with data like <input type=text>
I know how to render that text as html using:
#Html.Raw(Model.HtmlContent)
What I need now is that when the user type some thing and the form submit
the value of Model.HtmlContentupdate so I need some thing like #html.textboxfor(a=>a.HtmlContent) that return the updated value that what I mean by 2 way binding.
Thank you

How to retrieve both Text and Value from DropDownList in Asp.net mvc

I have a dropdownlist in asp.net mvc which is bound using the normal binding syntax
and I can retrieve the "value" in the controller.
But I also need to display the text that is associated with this value.
I can go the hard route and query the db for this associated value.
But I wanted to know if there is an easy way to retrieve the Text as well as the Value in the controller.
Sample code I used
<%= Html.DropDownList("State","Pick a State")%>
which displays
"NJ", "New Jersey" etc.
In Controller
public ActionResult SelectState(string State)
{
// I have value of State (NJ) ...I also need the Text for this
}
Any help would be appreciated.
Thanks
The value that will come as part of the form submission is the value of the dropdown item. To get both, you could change the value to be something like "value delimiter text", so something like "NJ|New Jersey". Then you could parse it in the controller.

How to serialize the checkbox in a form into Json data

We know that in MVC, a CheckBoxFor will generate a checkbox with a value="true" and a hidden with a value=false. Both input controls will share the same name.
It is very reasonable because the form will be able to POST a false value if the box is unchecked. And the model binder will ignore the hidden input when the checkbox return a true.
But now i have overridden the form submit event in order to send the form data into a WebAPI controller in JSON format.
When serializing the form data, there is no mechanism to parse the relationship between the checkbox and the hidden correctly. Therefore, when unchecked, it returns a false, which is okay. But when checked, it returns a {true, false} instead of true, because the serializeArray() function goes through every input and find two values goes to a same name.
The question is: What is the best way to correct it?
My solution to this problem was to write my own HtmlHelper method that renders a single <input type="checkbox" /> tag. Any other solution just seemed too hacky.
You can use dotPeek or .NET Reflector to look at how the Microsoft Team created the HtmlHelper.CheckboxFor method if you need any help accomplishing that task.
The 2 tag approach was taken to prevent MVC action parameters from throwing an exception when a "bool" parameter did not have a matching parameter sent to the controller (an unchecked checkbox doesn't send any value).

MVC4 Razor - #Html.DisplayFor not binding to model

I am trying to find me feet with MVC4 Razor and I'm stuck with this simple problem.
When I use #Html.DisplayFor the model is always sent back as NULL, but when I use #Html.TextBoxFor this model is fully populated, what am I missing?
Thanks in advance
This is a common issue that many people miss in the asp.net mvc framework. Not just the difference in the helpers such as HiddenFor, DisplayFor, TextBoxFor - but how exactly the framework sets up automatically collecting and validating these inputs. The magic is all done with HTML5's data-* attributes. You will notice when looking at the input tag generated that there are going to be some extra properties in the form of data-val, data-val-required, and perhaps some additional data properties for types, for example numerics would be data-val-number.
These data attributes allow the jQuery extension jquery.validate.unobtrusive.js to parse the DOM and then decide which fields to validate or generate error messages.
The actual collection of posted data is reflected from the name property. This is what should map up to the model that is in the c# or vb [HttpPost] method.
Use HiddenFor when you want to provide posted data that the user does not need to be aware of.
Use DisplayFor when you want to show records but not allow them to be editted.
Use TextBoxFor when you want to allow user input or allow the user to edit a field.
EDIT
"the purpose of this view is to enable the user to view the data before submitting it to the database. Any ideas how I can achieve this?"
You could accomplish this with a duo of HiddenFor and DisplayFor. Use HiddenFor to have the values ready to be posted, and DisplayFor to show those values.
DisplayFor will not do the Model binding. TextBoxFor will do because it creates a input element in the form and the form can handle it when it is being posted. If you want to get some data in the HttpPost action and you dont want to use the TextBoxFor, you can keep that pirticulare model proeprty in a hidden variable inside the form using the HiddenFor HTML helper method like this.
#using(Html.BeginForm())
{
<p>The Type Name is</p> #Html.DisplayFor(x=>x.TypeName)
#Html.HiddenFor(x=>x.TypeName)
<input type="submit" value="Save" />
}
Use both DisplayFor and HiddenFor. DisplayFor simply displays the text and is not an input field, thus, it is not posted back. HiddenFor actually creates <input type="hidden" value="xxxx"/>
DisplayFor builds out a HTML label, not an input. Labels are not POSTed to the server, but inputs are.
I know this is a bit of an old question but you can roll your own, custom combined display control as shown below. This renders the model value followed by a hidden field for that value
#Html.DisplayExFor(model => Model.ItemCode)
Simply use what the framework already has in place
public static MvcHtmlString DisplayExFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex)
{
var sb = new StringBuilder();
sb.Append(htmlHelper.DisplayFor(ex));
sb.Append(htmlHelper.HiddenFor(ex));
return MvcHtmlString.Create(sb.ToString());
}
Do you mean during a form post? If you use DisplayFor, this creates a element which does not contain any form values. Typically you use these in conjunction with each other to create a label for your textbox, then using the Html.TextBoxFor to allow users to modify the data element.
Example:
#Html.DisplayFor(x=>x.Item)
#Html.TextBoxFor(x=>x.Item)
Will Render
Item <a text input field following>
Or in HTML
<label for="Item">Item</label><input type="Text" id="Item" name="Item"/>

How to mimic MVC's checkbox -> bool model binding?

I've got an editor template which renders out a checkbox:
#Html.CheckBoxFor(model => model.Follow)
Which renders something like this:
<input checked="checked" data-val="true" data-val-required="The Follow field is required." id="Follow" name="Follow" type="checkbox" value="true" />
<input name="Follow" type="hidden" value="false" />
AFAIK the hidden field is something to do with catering when an unchecked box isn't sent to the server or something.
Anyway, if i take a look at the Request.Form["Follow"] when the checkbox is checked, i see a value of "true,false".
How do i coerce a bool from this value? Do i simply ignore the second field? (e.g the hidden field).
I'm doing this is a base controller (protected method, invoked from child controller), so i don't have a strongly-typed view model, only the raw Request object.
Can anyone help? Or alternatively, if someone could point me to where in the MVC source code this happens, i could take a look myself, but not sure where to start looking.
You are correct the hidden field is just so the form will be submitted to the server. Because if the form had just checkboxes that are not checked then nothing will be submitted and the server would not know to set them to false.
You only require 1 hidden field per form, you do not need one per checkbox. But if your making your own control it is hard to tell if a hidden textbox is already on the field or not. If you know you are always going to have a textbox or select list etc somewhere else on your forms you do not need a hidden textbox at all
You can rename your hidden textbox to anything name it "dummy" or something different to the checkbox name so Request.Form["Follow"]; will only return the value of the check box not need to split. You never need to check the value of the "hidden textbox".
On a side note you shouldn't be using Request.Form["Follow"] you Action method should have a parameter like this instead "bool? follow"
MVC helper renders checkbox input control with two input fields, the checkbox and the hidden, because the browser do not send a value for checkbox input field if the checkbox is not selected. If you do not use auto mapping, you need to parse the input value that you receve from your form.
Use this simple rule to detect the checkbox:
var rawFollow = Request.Form["Follow"];
if (rawFollow.Contains("true"))
{
// do something
}
As far as i know, the extra hidden field is because if the checkbox is NOT checked, that input will not be submitted with the form and therefore we need the hidden field with the value of false.
So the only solution is can think of is this:
var rawFollow = Request.Form["Follow"];
var rawFollows = rawFollow.Split(',');
if (rawFollows.Count() > 1)
{
rawFollow = rawFollows[0];
}
But this seems hacky (and what about the order of the elements on the page, what if for some reason the hidden field was FIRST, then it would always evaluate to false), which is why i'm wondering how the MVC source does this.

Resources