Confused about Usage of LabelFor() html helper in MVC 2.0 - asp.net-mvc

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.

Related

ModelState.IsValid for the unnecessary field Name

I have a very simple model. I have a location that has 2 fields, Id and Name. I have InventoryItems that has a number of scalar fields with a FK to the location at which it is stored. I have a View for creating an InventoryItem. The view has a drop down for `
<div class="editor-label">
#Html.LabelFor(model => model.Location)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Location.Id, new SelectList(ViewBag.Locations, "Id", "Name"))
</div>
The controller code checks ModelState.IsValid which is returning false because the NAME of the location in the ModelState is empty. I really only need the Id to save the InventoryItem. But I have [required] in the Location Name field because when I go to allowing the addition of Locations, I want that field required.
Can someone tell me the CORRECT way to deal with this in the MVC design pattern?
Well if the name is already set before this point you could just use a #Html.HiddenFor() to hide the name on the page it keeps the value for the HttpPost.
If this isn't the case then I suggest dropping the required requirement on the name in the model itself and use it on a View Model, this way you can have two different levels of validation, just bare in mind you need to make sure that if the field isnt populated at the point where it's needed it will error.
Personally I would use View Models whenever you have changing validation requirements
The best way to go about it is to use ViewModel that have only the fields you need on the UI side and then convert to your actual Model in the controller.
In your case, you could use a LocationLink in your View/Form that only takes an Id like:
public class LocationLink
{
[Required(ErrorMessage = "No id provided")]
public string Id { get; set; }
}
Then in your controller you load the appropriate Location from your data store with the supplied Id and add that to the parent model.
Usually you should have a ViewModel for Display with all the fields (Locationwith Id and Name) and a ViewModel for create/edit forms (LocationLink in that case with only Id).

getting dropdown's text in Post action method

I have a Razor view in my asp.net MVC3 application with a dropdownlist like this:
#Html.DropDownListFor(model => model.Account.AccountType, new SelectList(Model.AccountTypes, "AccountTypeCode", "Abbreviation"))
This dropdown is inside a form. When form is posted to action method and viewmodel is filled because of model binding, It get the value(AccountTypeCode) and not the text "Abbreviation" property of dropdownlist. I want to get both of these. how can I get these in post action method.
Please suggest.
If you need more than one property of an object as a value for a dropdown, the easiest way is to create a combination of these in a partial class
EF 4, how to add partial classes this quesion should help you. You will be able to combine values under one property that you will provide to your dropdown helper.
If you don't want to use partial classes I would advise creating your own helper, that will be a lot easier than trying to use something that does not fit your needs. You can do something like :
#helper CustomDropdown(string name, IEnumerable<AccountTypes> valueList)
{
<select>
#foreach (var item in valueList)
{
<option value="#item.Abbreviation #AccountTypeCode">#item.Abbreviation</option>
}
</select>
}
Google "Creating an Inline HTML Helper" to get some valuable resources on that topic
I struggled with this recently, and the best I could do was:
ViewBag.Message = myModel.myProperty.ToString().
in the controller action. Assuming myProperty is AccountType.
Then in my view I just did
#ViewBag.Message
The next problem I encountered is that it spit out the exact text, without spacing. I had to use a helper to add spacing (but it was based on each word being capitalized, so "ThisIsSomeText" would show up as "This Is Some Text".

ASP.NET MVC: DropDownList -- Of DataSource, SelectedItem, and inline code access within the View

As far as I can tell, there are 3 ways to create a DropDownList in an ASP.NET MVC View:
Hand code the HTML manually
<asp:DropDownList ID="someID" runat="server"></asp:DropDownList>
<%= Html.DropDownList("someID") %>
I think we can all agree that #1 is (generally) a waste of time.
With #2, it appears to be the "WebForms" way of doing it, but has an advantage in that if you're writing a View you can have access to the object you've created via inline code that occurs after it. For example:
<asp:DropDownList ID="someID" runat="server"></asp:DropDownList>
<%
someID.SelectedIndex = 0;
string someString = someID.SelectedValue.ToString();
%>
This does not appear to be possible with #3.
The nice thing that I've discovered about #3 (the HTML Helper way) is that by passing it a string, it sets the Name and ID to the string as well as uses the string to search the ViewData dictionary and auto-generate the respective tags for the DropDownList based on the SelectList that was added to the ViewData dictionary that was added in the calling Controller.
// controller code
ViewData["someID"] = new SelectList(someMethod().ToList());
For the life of me, I cannot figure out if there is a way to auto-generate the tags with <asp:DropDownList> or if I have to manually create them myself.
What's generally the best approach for implementing a DropDownList in ASP.NET MVC?
<%= Html.DropDownList("name", new SelectList(someEnumerable, "valueProperty", "textProperty")) %>
where someEnumerable is a property on your viewModel.
for example:
class Person
{
int id;
string name;
}
class myVM
{
IEnumerable<Person> people;
}
<%= Html.DropDownList("name", new SelectList(Model.people, "id", "name")) %>
Edit dont make the SelectList in your controller, this is view specific code and belongs in the view, just send your IEnumerable in the viewmodel.

mvc modelbinding

I have an Edit action/view for my User object, but only want a few fields to be editable.
I've set up the view to bind to the User object, and am using Html.EditorFor() for the few fields that I want to be editable.
I noticed in my User object on Post:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditUser(Mynamespace.User user)
{ }
that only the fields that I provided .EditorFor() controls for actually have any data.
I tried using Html.Hidden(Model.ID) for one of the fields that i didn't want to be editable, but it is null in the new User object created from model binding.
So, my question- How do I bind where only a couple of the fields should be editable?
Thanks!
It sounds like you probably want to start thinking about using a View Model that is specific to the form/input that you're dealing with. But in the short term, ....
You could bind to a FormCollection parameter instead and copy the values manually, OR...
you can use the TryUpdateModel method to populate this existing user object with the new data.
Here's the documentation for TryUpdateModel:
http://msdn.microsoft.com/en-us/library/dd470756.aspx
It's still possible for malicious users to send phony form-values that map to real properties on your model, so to protect against this (like an employee changing his salary property with a simple form hack) you can introduce an interface that contains the white list properties that you allow.
Here's an example:
public interface IUserEditableFields
{
string Username {get;set;}
string Email {get;set;}
}
//... in the controller action
if(TryUpdateModel<IUserEditableFields>(user)) {
//validation passed
//only Username and Email were editable
}
This is a good resource on how to do this:
http://css.dzone.com/news/aspnet-mvc-think-before-you-bi
Are you using the strongly-type helper for the hidden field or is it exactly like you've typed. If you've got it exactly as typed, then the name of the hidden field is the value of the id, not the name of the property on the model (ID). You might want to change it to:
<%= Html.Hidden( "ID" ) %>
or (if using strongly-typed helpers)
<%= Html.HiddenFor( m => m.ID ) %>
Ben's answer is largely correct, in that a ViewModel might be more appropriate, and short of that, TryUpdateModel can be used. However, I add that in that case, rather than requiring the domain object to implement a new interface, you use the overload TryUpdateModel<T>(T, string[]), which allows you to whitelist the updateable properties in a string array by name.

Disabled Form Elements ASP.NET MVC Update

I'm wanting to update a record in my database which has two values, one is the ID, and one is the "description". The ID can never be changed, however I'm relying on the use of strongly-typed features to do it. So, I have the following:
Inherits="System.Web.Mvc.ViewPage<Business>"
Which is fine as it allows me to get everything back. The problem is when I use the following line:
<%= Html.TextBox("BusinessID", ViewData.Model.BusinessID, new { disabled = "disabled", style = "width:50px;", #class = "uppercase", maxlength = "4" })%>
With the disabled = "disabled" option it doesn't recognise the BusinessID and therefore doesn't pass it back to the controller which, in turn has problems binding the object up.
Not that you'll need it, but here's the controller action:
[HttpPost]
public ActionResult EditBusiness(Business business)
{
if (!ModelState.IsValid)
return View(business);
// update business here
_contractsControlRepository.UpdateBusiness(business);
return RedirectToAction("Businesses");
}
Any ideas why this is happening? I didn't realise form elements were completely hidden on postback when they're disabled. I don't want the users editing that particular field. I've also tried Html.DisplayFor(b=>b.BusinessID) without any luck.
display the id like this
Html.Hidden("BusinessID", ViewData.Model.BusinessID)
<%=Model.BussinessID %>
this way you will have the id for the binding in the hidden tag
and you will display the value in the label
or you can use anything else that you want yo can do like this also
<input type="text" value="<%=Model.BussinessID %>" contentEditable="false">
and put the hidden somewhere in the form
instead of Html.Textbox you can use Html.Hidden("BusinessID", ViewData.Model.BusinessID)
You always have the option of either "hard-coding" the html element, or writing your own html helper method to do it.
public static string DisabledTextBox(this HtmlHelper helper, string name, object value)
{
return String.Format(#"<input type="text" name="{0}" id="{0}" disabled="disabled" value="{1}" />", name, value);
}
Is there a particular reason you are displaying the id? if not then leave it out and on your controller simply use TryUpdateModel() instead.
or is that not what your asking?
edit
<%= Html.TextBox("name","value", null, new { style="readonly"}) %>
Edit 2
You might think about doing a route like //site/controller/yourbusinessid
then you can use the id as it's passed to your controller and you can then, in your view, simply use <%= Model.BusinessId %> as a string.

Resources