I'm using an MVC 3 view which has a Model inherited:
Inherits="System.Web.Mvc.ViewPage<MyModel>"
I use html helpers to populate model properties:
<td><%=Html.TextBoxFor(i => Model.partA, new { #style = "width:25px;", #maxLength = 3})%></td>
<td><%=Html.TextBoxFor(t => Model.partB, new { #style = "width:35px;", #maxLength = 5 })%></td>
The problem is in my controller 'partB' gets the value from my TextBoxFor helper but 'partA' is empty. There's other parts of the model but I use this as an example.
It's the same model based on the same table in my entity framework. I checked the properties and they're both intergers with Nullable set to (none). In SQl Server MS, the table fields it's refering to appear to be the same also. Both are set (int, null).
I don't see what the difference is that causes partB to be populated and partA to be empty.
What else can I check?
OK, it was because I had a textbox also named 'partA' in a control being rendered in my page. The empty value in the control seemed to be overwriting 'partA' on my view.
Related
I am working on an ASP.NET MVC-4 web application. I'm defining the following inside my action method to build a SelectList:
ViewBag.CustomerID = new SelectList(db.CustomerSyncs, "CustomerID", "Name");
Then I am rendering my DropDownListFor as follow inside my View:
#Html.DropDownListFor(model => model.CustomerID, (SelectList)ViewBag.CustomerID, "please select")
As shown I am naming the ViewBag property to be equal to the Model property name which is CustomerID. From my own testing, defining the same name didn't cause any problem or conflict but should I avoid this ?
You should not use the same name for the model property and the ViewBag property (and ideally you should not be using ViewBag at all, but rather a view model with a IEnumerable<SelectListItem> property).
When using #Html.DropDownListFor(m => m.CustomerId, ....) the first "Please Select" option will always be selected even if the value of the model property has been set and matches one of the options. The reason is that the method first generates a new IEnumerable<SelectListItem> based on the one you have supplied in order to set the value of the Selected property. In order to set the Selected property, it reads the value of CustomerID from ViewData, and the first one it finds is "IEnumerable<SelectListItem>" (not the value of the model property) and cannot match that string with any of your options, so the first option is selected (because something has to be).
When using #Html.DropDownList("CustomerId", ....), no data-val-* attributes will be generated and you will not get any client side validation
Refer this DotNetFiddle showing a comparison of possible use cases. Only by using different names for the model property and the ViewBag property will it all work correctly.
There is not harm to use it. You will not get any error. but best practice is to bind model property.
In an MVC view with a form on it and given the following code using HTML helpers:
#Html.TextBoxFor(m => m.FirstName, new { id = "firstName", maxlength = "50", #class = "form-input" })
Is there a way to stop this form automatically populating the fields with data? I know it's by design and in most cases is helpful but in this case I want to be able to turn that functionality off.
To clarify - If I have a ViewModel with this property in it:
[Display(Name = "First Name")]
public string FirstName { get; set; }
I understand that the HTMLHelper TextBoxFor will allow me to use the strongly typed
m => m.FirstName
when creating the input.
That's fine. However, if I have the ViewModel populated with data then it also shows this data in the input field, this is by design and I get that.
Now, imagine you wanted the strength of the strongly typed aspect but without the automatic filling of the data.
The only option appears to be:
#Html.TextBox("myTextBox", "value goes here", new { #class = "form-control" })
Which is brittle where the name / id values are concerned. I prefer the strongly typed nature of the TextBoxFor but can't have that without also automatically showing whatever the ViewModel data is.
It sounds like you're talking about the browser behaviour here, so you want to turn off autocomplete. You can use this on a per input basis:
#Html.TextBoxFor(m => m.FirstName, new { ..., autocomplete = "off" })
Or you can do it on the whole form:
#Html.BeginForm(action, controller, FormMethod.Post, new { autocomplete="off" })
EDIT:
Reading your comments it seems you're populating the view model with the values and seeing them when you render the view. In which case, the answer is simple, reset the model before passing it to the view:
return ViewModel(new TModel());
While passing the viewmodel to view in controller you can set those properties to blank value or null for which you want empty textboxes in UI.
I've encountered what seems to be a strange inconsistency in the values of properties in my model.
I have the following controller action...
<Route("news/edit")>
<HttpGet>
Function EditIndex(Optional filter As Models.NewsFilter = Nothing) As ActionResult
filter.Start = 0
filter.Count = 100
Return View("EditIndex", filter)
End Function
Most of the properties in the model come from the querystring, but my controller explicitly setting "Start" and "Count", and then passing the model to the view.
My view is declared like so...
#inherits System.Web.Mvc.WebViewPage(Of Models.NewsFilter)
The odd thing is that if I simply display the models properties within the view like...
Start=#Model.Start
Count=#Model.Count
They display the values as defined in my controller. However when I use the following...
#Html.EditorFor(Function(m) m.Start, New With {.class = "form-control"})
#Html.EditorFor(Function(m) m.Count, New With {.class = "form-control"})
The values displayed are the original values from the QueryString. It's ignoring the values that I've set in my controller.
I don't understand why this happens. Is it trying to be clever and automatically checking the QueryString parameters because it's within a form?
I am working on an MVC 2.0 C# web Applciation. In one of my form, i am using LabelFor() html helper.
I am using the following syntax:
<%=Html.LabelFor(model=>model.Addedon)%>
Here, for this label i would like to associate a initial value that is DateTime.Now
I tried some thing like this:
<%=Html.LabelFor(model=>model.Addedon,new{value=DateTime.Now})%>
But, i am getting an error saying that there is no over load for this helper taking two arguments.Please help
UPDATED:
The form is create form/ add form which makes an insert operation. So, i am building a model and updating that model to the database.
In that model, i have a field called createdby. So, i need to associate this value with the username logged in and doing the insert operation.
So, how to associate this username value with the model field and i need to display as label so that it will be read only field.
Hope this makes clear..
LabelFor is only for, you guessed it, rendering a <label> element.
It also uses the [Display] and [DisplayName] attributes, so you can have a strongly-typed label with custom name.
What you're after is probably this:
<div>
<%= Html.LabelFor(model => model.Addeon) %>
</div>
<div>
<%= Html.DisplayFor(model => model.Addeon) %>
</div>
So the LabelFor will generate the property name description (e.g. 'Addeon'), while the DisplayFor will render the property value. DisplayFor can use the [DisplayFormat] attribute if you need custom formatting. You can set the default property value in the view model's constructor:
public class ViewModel
{
[Display(Name = "My awesome date")]
public DateTime Addeon {get;set;}
public ViewModel()
{
Addeon = DateTime.Now;
}
}
[EDIT]
Actually, your edit would make for a good second question instead of putting it here. Anyway, in your situation I'd create a dedicated view model that would hold the properties you need (e.g. user name) and would be filled in controller. Everything else would be conceptually the same - view would bind to the view model.
I have the following two items , one which is readonly:-
#Html.TextBoxFor(model => model.Technology.Tag, new
{ #readonly = "readonly" })
While the other is Disabled:-
#Html.DropDownListFor(model => model.Customer.NAME, ((IEnumerable<TMS.Models.AccountDefinition>)ViewBag.Customers).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.ORG_NAME),
Value = option.ORG_NAME.ToString(),
Selected = (Model != null) && (Model.Customer != null) & (option.ORG_NAME == Model.Customer.NAME)
}), "Choose...", new { disabled = "disabled" })
so will the asp.net mvc model binder bind the two items? , or it will ignore any read-only and any disabled fields ?
It will bind them, but as long as you have populated them with the correct data, that shouldn't matter. Also, you can have your code that maps these models to the entity, assuming you are using view models, just ignore the values in question. Assuming this is a standard HTTP Post from the form, HTTP will not post disabled or readonly fields, which means they will be null or the default value in the model, so you need to account for that.
If you want the binder to ignore these values, use TextBox and DropDownList and make sure they are not named the same as your properties. If you do not use 'For' you will need to add code in the view to set the values.
ReadOnly text fields get bound.
I've been trying to find a way around the unbound dropdownboxfor values. Here's what I came up with:
$('#xxx').change(function() {$(this).val(lastSel_xxx);});
var lastSel_xxx = $("#xxx option:selected").val();
Use the code above for each HTML element in your view (this will require you to document each ID output) and replace 'xxx' with the element name.
When a user selects another option besides the initial option selected, it reverts back to the original.
HOpe this helps!