ASP.NET MVC - drop down list selection - partial views and model binding
Asked Answered
S

1

5

I'm fairly new to ASP.NET MVC and am trying to work out the best way to do this. It's probably simple but I just want to do things correctly so I thought I'd ask.

Lets say I have a model that is this:

Task - Id, Description, AssignedStaffMember

StaffMember - Id, FirstName, LastName

and in my view I want to create a new task. I make a strongly typed Razor view, and can use EditorFor to create textboxes for Description but what about AssignedStaffMember?

I want a drop down list of all current staff and have the option of selecting one, then this gets submitted to an action method which is NewTask(string description, StaffMember assignedStaffMember) either that or I could have an int for staffId instead of the StaffMember object and look it up in the action method.

What is the best way to do this? I need to go to the database to get the list off staff, so here's what I thought:

  1. Make a partial view for the listing of staff drop down, which will be used a few times and use @Html.Action("ListStaff", "Staff") to call it. The action method then has

    public ActionResult ListStaff()
    {
        IEnumerable<StaffMember> model = _serviceLayer.GetAllStaff();
        return PartialView(model);
    }
    

    However I'm not sure on how this will work with model binding, my understanding is that it has to have the correct name for the form to submit it, I'd need to pass the name to the partial view to put on the element I guess?

  2. Instead of having it call a controller to get the staff, make a ViewModel that contains my Task and a IEnumerable possibleStaff collection. possibly send this information to a partial view.

  3. a Html Helper ?

  4. EditorFor could somehow be used?

which one (or is there more) would be best? and how would I do the model binding?

Stump answered 4/3, 2011 at 1:7 Comment(1)
+1 for the nice example you used describing your problem :)Importunate
P
18

Here is one way to do this. Create a TaskDetailsViewModel

public class TaskDetailsViewModel
{
    public TaskDetailsViewModel()
    {
        this.Task = new Task();
        this.StaffMembers = new List<StaffMember>();
    }

    public Task Task { get; set; }
    public IEnumerable<StaffMember> StaffMembers { get; set; }
}

In Controller

public ActionResult Edit(int id)
{
    var task = taskRepository.GetTaskByID(id);

    var taskDetailsViewModel = new TaskDetailsViewModel();

    // Populate taskDetailsViewModel from task and staff

    return View(taskDetailsViewModel);
}

[HttpPost]
public ActionResult Edit(TaskDetailsViewModel taskDetailsViewModel)
{
    if (ModelState.IsValid)
    {
        taskRepository.Save(taskDetailsViewModel.Task);
    }
    else
    {
        // Show Error
    }

    return View(taskDetailsViewModel);
}

In View (bound strongly to TaskDetailsViewModel)

@Html.DropDownListFor(model => model.Task.AssignedStaffMember, new SelectList(Model.StaffMembers, "ID", "FirstName", Model.Task.AssignedStaffMember))
@Html.ValidationMessageFor(model => model.Task.AssignedStaffMember)
Psittacosis answered 4/3, 2011 at 1:38 Comment(1)
Thanks for this, I was leaning towards trying this way. I'm having a problem though. It doesn't seem to be binding the drop down list correctly in the Edit post method - the AssignedStaffMember is always null. Got me thinking, I'll still need to look up that staff member in the database once I bind it, because even if it did work, I'd just have a staff member that was empty except for its ID wouldn't I? which is not overly useful. So perhaps I should just accept parameters separately for that?Stump

© 2022 - 2024 — McMap. All rights reserved.