ASP.NET MVC - drop down list selection - partial v

2019-01-18 07:40发布

问题:

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?

回答1:

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)