I've been trying to debug an issue and I pinned pointed it down to this scenario:
When the statement Html.TextBox("ID", "What the heck..") is executed, I expect it to render:
<input id="ID" name="ID" type="text" value="What the heck.." />
But I get a Guid as its TextBox value such as so:
<input id="ID" name="ID" type="text" value="2e369d2c-071d-4733-8382-cc9e77d0b912" />
Why is Asp.net MVC outputting Guids? I'm not overriding asp.net mvc's framework methods. Please refer to the screenshot.
Update:
Here's another screenshot using Html.Hidden() instead of Html.TextBox(). I couldn't use Html.HiddenFor() directly into the Watch window because HiddenFor() uses lambdas.
#Eric Petroelje and #TLS: You two are correct. TextBox() and Hidden() is retrieving ID's value from the POST variables and not from the current Model or the function's value parameter. Though, I've expected different from HiddenFor() and TextBoxFor(). I expected it to get its value from the POST'ed variables only if it cant get it from the current Model. How can I achieve this?
Maybe you have a POST variable named ID that is a GUID? If that's the case, the HTML Helper method will use that POST value. If no POST value is present, it will fall back to the value in the model.
You are correct that Html.TextBox("ID", "What the heck..") is expected to output the attribute values that you give in your first example; however, if you are using the Html.TextboxFor method, then you're using a MVC Helper that dynamically loads the value of the ID property and places that into the value attribute in the HTML. When you use the Html.TextboxFor method, your second example is the expected HTML output if your ID property is a Guid.
Related
Is there an attribute or something similar in Asp MVC to indicate that a property should only come from the client, i.e. it shouldn't be roundtripped.
So
#Html.HiddenFor(x => x.MyProp)
I set this somehow on the client together with some other properties, it goes the server, server has a model error so sends it all back. I don't want this one property to be roundtripped.
The best I can think of is to do this
<input type="hidden" name=MyPropOneWay />
Then I manually insert it at the controller end into the property
(Addition)
It's not to avoid model errors, it's because there are a few ways of submitting the form, this is a shortcut method. In no circumstance do I want this value to be roundtripped as otherwise it will look like it's been set when it hasn't, however I do want everything else to be roundtripped
Thanks
If you don't want the value rendered from the server (either initially or after a roundtrip), use:
<input type="hidden" name="#Html.NameFor(m => m.MyProp)" />
This will render an input hidden element without a value, but it will still have the correct name to automatically bind to your model on form submission. Which effectively makes it "one way".
(The NameFor helper was added in MVC4)
I have a model..
Models.Mm.Items.ItemEditModel like thiss..
in ItemEdit View
#Html.TextBoxFor(m => m.RecordTypeId) --> this works bind model and take value RecordTypeId
#Html.Kendo().NumericTextBoxFor(m => m.RecordTypeId) --> this works
<input id="RecordTypeId" name="RecordTypeId" type="text" /> --> this not working this value is null
I am using autofac and kendo.
I could not understand why html binding not working..
There is not enough information here to give you the real cause of the problem, but one thing you can check is the name attribute of the input element generated by the first two methods.
Mvc use the name attribute to bind your model so if this name does not match what he expect for the property of the mod
I m new to MVC and confused what is difference in <Input type="Checkbox">, #HTML.CheckBox and #HTML.CheckBoxFor.
Can you please guide why two helpers are provided for same thing ? In which situation which one should be used ?
Thanks
Edit:
Added Input type=checkbox
<Input type="Checkbox"> is Html markup for a checkbox and #Html.CheckBox & #HTML.CheckBoxFor are Html Helpers for Razor view engine..
suppose your viewmodel has a property Person.HadDinner, then usually for model binding to work properly you will have to name the checkbox Person.HadDinner and id as Person_HadDinner..
you can use #Html.CheckBox like
#HTML.CheckBox("Person.HadDinner", Model.Person.HadDinner)
but if you are using #HTML.CheckBoxFor, it will be strongly typed..
#HTML.CheckBoxFor(x => x.Person.HadDinner)
in both the cases, final output markup will be
<input type="checkbox" id="Person_HadDinner" name="Person.HadDinner">
The CheckboxFor (MSDN)
Returns a check box input element for each property in the object that
is represented by an expression.
This means a checkbox element is created for each property in the expression provided. Where as Checkbox (MSDN)
Returns a check box input element by using the specified HTML helper
and the name of the form field.
This creates a simple Checkbox element with the (optional) attributes provided.
Typically when referencing a property of an object (or the View Model) the most desired technique is to use CheckboxFor as the checkbox will be formatted correctly against your model.
Hope this helps.
EDIT: Response to OP Changes.
Both the CheckboxFor and Checkbox generate standard HTML output such as below.
#Html.CheckboxFor(m => m.SomeProperty)
<input type="checkbox" name="SomeProperty" id="SomeProperty" />
#Html.Checkbox("SomeProperty")
<input type="checkbox" name="SomeProperty" id="SomeProperty" />
The helper methods simply generate the HTML required to meet the expressions and attributes defined in the helpers.
Additionally, you dont have to use the helpers. You can write your HTML elements directly as needed.
I have a small problem.
I want to have dropdown list with some objects. After clicking on one I want to add it to list with textfield for naming it. I don't want to limit quantity of this fields. I want to receive in controller ID (stored in dropdown list) and name (given by user) for each selected item. How can I do it?
I was thinking about storing it in some fields as a text, and parsing in cotroller but I think it's not elegant.
EDIT.
Ok, Thansk for your help, but it's not working for me correctly.
I generate html like this:
<input type="hidden" value="96" name="Inputs[0].Key">
<input type="text" name="Inputs[0].Value">
In my controller I'm receiving this dictionary. The problem is that quantity of elements is correct, but all values are null. What is wrong here?
The best way to go about this is by using array-style model binding.
So, for each element you wish to name you create a hidden field to store the drop down value plus a text field to store the user-given name. You name them as follows:
<input type="hidden" name="element[0].Key" /><input type="text" name="name[0].Value" />
increasing the index value each time. This is easily achieved with a bit of JavaScript. You then create an action method which takes a KeyValuePair<string, string>[] as a parameter. You will then be able to parse through your values no problem with a loop or LINQ expression.
Use IEnumerable<KeyPairValue<string,string>> MySelectedItem = new List<KeyPairValue<string,string>>(); on model, and when adding it to the list, name it like an array:
MySelectedItem[1].Key, MySelectedItem[1].Value, MySelectedItem[2].Key...
(I haven't tested this, but it should work)
Edit: check out this blog post with better explanation on how to do it: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
I create a strongly typed form like this in my controller:
return View("BlaForm", Bla);
In the view I use something like this:
(1)
<%= Model.Version %>
(2)
<%= Html.Hidden("Version", Model.Version)%>
Here (1) is just for debugging purposes.
After a successive update of my object this produces something like this:
(1)
10
(2)
<input id="Version" name="Version" type="hidden" value="9" />
The hidden value is out of synch for some strange reason ???!!! The Version value was definitely 10 in this case as established by the debugger. Why is this? Are hidden value somehow cached?
Thanks.
Christian
PS:
I also do:
if (TempData["ViewData"] != null)
{
ViewData = TempData["ViewData"] as ViewDataDictionary;
}
in the controller action to maintain form values in case validation errors happen. This seems to be the reason. But still I explicitely do: <%= Html.Hidden("Version", Model.Version)%> .... ???? Maybe I missunderstand the lif cycle a bit?
Html helper will always use the value in the GET or POST request before the value in your model or ViewData. This means that if you post Version=9 to a controller action and inside this action you try to modify its value to 10, when you return the View, the Html.Hidden helper will use the POSTed value and not the one in your Model. The only workaround is a custom HTML helper or simply:
<input id="Version" name="Version" type="hidden" value="<%= Model.Version %>" />
HTML helper will always look for values in ModelStateDictionary, then in ViewData and after this use the value parameter given into helper method.
The 2 other places are in your case.
ModelState state = this.ViewData.ModelState["Version"];
state.Value; // this is the value out of the ModelStateDictionary
object value = this.ViewData["Version"]; // this is the value if set
// out of the ViewData Collection
The ModelStateDictionary gets its entries, while model binding. If you have the Version as a action method parameter, the Modelbinder (in your case the DefaultModelBinder) will enter the key version with the supplied value of get or post request.
If you change the value, put it in your model, you have to update the ModelStateDictionary too.