50

It seems weird that I couldn't find an explanation of the difference between those two helpers, so I would assume that is something obvious but I missed.

Basically I am trying to decide which one I should use for my case, with the following simple Model:

public class Booking
    {
        public int ID { get; set; }
        public Room Room { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public ICollection<Equipment> Equipments { get; set; }
        public string Who { get; set; }
    }

and I want display a simple Room DropDownlist for Adding and Editing Booking record.

After doing a lots of Google around, it seems that I probably need a DropDopwListFor, but not sure why and how?

Morteza Azizi
  • 479
  • 5
  • 23
Paul L
  • 2,240
  • 5
  • 36
  • 55
  • 1
    Thank for the good examples, make sense and my question trivial :D. But why everyone give me an example of Dropdownlist for Equipment, but I am asking for an working example of room, but I assume they will working pretty much same way? – Paul L Nov 22 '11 at 23:37

4 Answers4

98

Take the following two examples:

@Html.DropDownListFor(
    x => x.EquipmentId, 
    new SelectList(Model.Equipments, "Id", "Text")
)

and:

@Html.DropDownList(
    "EquipmentId", 
    new SelectList(Model.Equipments, "Id", "Text")
)

It is obvious that with the second example the name of the property you are binding the dropdown to is hardcoded as a magic string. This means that if you decide to refactor your model and rename this property Tooling support that you might be using has no way of detecting this change and automatically modifying the magic string you hardcoded in potentially many views. So you will have to manually search & replace everywhere this weakly typed helper is used.

With the first example on the other hand we are using a strongly typed lambda expression tied to the given model property so tools are able to automatically rename it everywhere it is used if you decide to refactor your code. Also if you decide to precompile your views you will get a compiler time error immediately pointing to the view that needs to be fixed. With the second example you (ideally) or users of your site (worst case scenario) will get a runtime error when they visit this particular view.

Strongly typed helpers were first introduced in ASP.NET MVC 2 and the last time I used a weakly typed helper was in an ASP.NET MVC 1 application long time ago.

SharpC
  • 6,974
  • 4
  • 45
  • 40
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 1
    Update for V6 - you can obviously bypass the magic string using the new nameof keyword (nameof(x.EquipmentId) which results in EquipmentId. – TomTom Jan 21 '16 at 18:28
  • So does that mean that "Method 2" is in effect depricated? Is there ever any reason to use it? – David Britz May 27 '20 at 03:53
  • An interesting thing that I found is that when I used the 2nd approach (which is the generated method) when I changed my int to int? which allows for null values. It was still required in the edit view if I was trying to change a value to be null. It worked fine with create and would save a null that way. Using DropDownListFor made it validate correctly. – Paul Hegel Jun 17 '20 at 22:55
6

DropDownListFor will automatically select the selected value by using the specified property:

// Will select the item in model.Equipments that matches Model.EquipmentId
@Html.DropdownListFor(m => m.EquipmentId, Model.Equipments); 

Another comment:

Don't have ICollection<Equipment> Equipments in your view model. You should have a property that returns an IEnumerable<SelectListItem>.

SharpC
  • 6,974
  • 4
  • 45
  • 40
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • Thanks for help me. But I am actually asking for Room drop down list, just trying to get the idea. Also, don't understand your example in view code about DropdownListFor for equipments. Seems you suggesting that I add a ViewModel that return an IEnumberable in my ViewModel and return that from controll to my view instead of Booking model? Could you please provide an fully working example base on my model or a better one? I am stuck now because I couldn't found an working example which I can fit into my model. – Paul L Nov 19 '11 at 06:02
2

DropdownListFor is support strongly type and it name assign by lambda Expression so it shows compile time error if have any error.

DropdownList not support this.

Shree Krishna
  • 8,474
  • 6
  • 40
  • 68
Sabuj Sen
  • 21
  • 1
2

When you want to add a view (aspx file) where this DropDownList or DropDownListFor will be inside, rightclick->add view then select "Create a strongly typed view" then in list select Booking class. After that add this page.

You can write in it as follows:

@Html.DropdownListFor(m => m.Equipments , Model.Equipments);

because we add strongly typed view as Booking, you can have:

m => m.ID, m => m.Room, m => m.StartTime

... etc.

In your services you can have methods to take data from database, then use this service's method in your controller to pass data from database to view. You can use ViewData in your controller:

ViewData["Equipments"] = new servicename().getdatalistfromdatabase().AsEnumarable();

Putting AsEnumarable() at the end of your list taken from database makes it IEnumarable.

Then in your view, you can also have :

@Html.DropdownList("MyEquipments" , ViewData["Equipments"]);

A link on ViewData usage: http://msdn.microsoft.com/en-us/library/dd410596.aspx

I hope that helps you.

SharpC
  • 6,974
  • 4
  • 45
  • 40
cemsazara
  • 1,623
  • 15
  • 14
  • the link in your answer is dead – Dakait Mar 07 '13 at 10:53
  • I believe ViewData was replaced by ViewBag in MVC 3: http://weblogs.asp.net/scottgu/announcing-asp-net-mvc-3-release-candidate-2 ViewBag has strongly-typed properties as opposed to the strings used in ViewData. It's the same rationale for why we should use DropDownListFor rather than DropDownList. – Simon Elms Aug 17 '15 at 03:25