Элементы DropDownList нулевые при публикации для редактирования формы - PullRequest
6 голосов
/ 06 марта 2011

Итак, у меня есть страница для редактирования сотрудников.

Вот моя модель просмотра:

public class EmployeesViewModel
{
    [HiddenInput(DisplayValue = false)]
    public int EmployeeId { get; set; }      

    [Required(ErrorMessage = "Position is required")]
    [DisplayName("Position")]
    public int EmployeeTypeId { get; set; }

    [Required(ErrorMessage = "Name is required")]
    [DisplayName("Name")]
    public string Name { get; set; }


    public IEnumerable<EmployeeType> EmployeeTypes { get; set; }
}

Вот мой контроллер:

public class EmployeesController : Controller
{
    public ActionResult Edit(int id)
    {
        //get employee from id
        var employee = GetEmployee(id);

        if (employee != null)
        {
            var viewModel = new EmployeesViewModel
            {
                EmployeeId = employee.EmployeeID,
                EmployeeTypeId = employee.EmployeeTypeID,
                Name = employee.Name,

                EmployeeTypes = _adminRepository.GetAllEmployeeTypes(),                    
            };

            return View(viewModel);
        }

        //if no employee exists for this id, redirect to the Create page and display a friendly message
        TempData["message"] = "No employee exists with an ID of " + id + ", you can create a new employee here.";
        return RedirectToAction("Create");
    }



    [HttpPost]
    public ActionResult Edit(EmployeesViewModel viewModel)
    {
        //if editing an employee, fetch it; otherwise, create a new one
        Employee employee = GetEmployee(viewModel.EmployeeId);
        TryUpdateModel(employee);

        if (ModelState.IsValid)
        {              
            SaveEmployee(employee);
            TempData["message"] = "Employee has been saved.";
            return RedirectToAction("Details", new { id = employee.EmployeeID });
        }
        return View(viewModel);     // validation error, so redisplay same view
    }
}

И мой Editпросмотреть страницу:

<%@ Page Title="" Language="C#" MasterPageFile="/Admin.Master" Inherits="System.Web.Mvc.ViewPage<EmployeesViewModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

    <h1>Edit Employee</h1>

    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm("Edit", "Employees", FormMethod.Post)) { %>

        <%: Html.HiddenFor(m => m.EmployeeId)%>

        <div class="editor-label"><%: Html.LabelFor(m => m.EmployeeTypeId) %></div>
        <div class="editor-field">
            <%= Html.DropDownListFor(m => m.EmployeeTypeId, new SelectList(Model.EmployeeTypes, "EmployeeTypeID", "Position", Model.EmployeeTypeId), "- Select an Employee Type -")%>
            <%: Html.ValidationMessageFor(m => m.EmployeeTypeId)%>
        </div>

        <div class="editor-label"><%: Html.LabelFor(m => m.Name) %></div>
        <div class="editor-field">
            <%: Html.TextBoxFor(m => m.Name)%>
            <%: Html.ValidationMessageFor(m => m.Name)%>
        </div>

        <p>
            <input type="submit" value="Save" />
            <%: Html.ActionLink("Cancel", "Index") %>
        </p>

    <% } %>

</asp:Content>

После отправки моей формы, она заканчивается на if (ModelState.IsValid).Он пытается снова отобразить представление при вызове return View(viewModel);, и я получаю это сообщение об ошибке:

Значение не может быть нулевым.

Имя параметра: элементы

<% = Html.DropDownListFor (m => m.EmployeeTypeId, новый SelectList (Model.EmployeeTypes, "EmployeeTypeID", "Position", Model.EmployeeTypeId), "- выберитеТип сотрудника - ")%>

Я не уверен, почему это происходит.Раскрывающийся список загружается правильно, когда я перехожу на страницу, но не при повторном отображении представления.

Кто-нибудь знает, что здесь происходит?

Ответы [ 2 ]

10 голосов
/ 06 марта 2011

Вам необходимо перезагрузить свойство EmployeeTypes вашей модели представления из вашего хранилища, прежде чем снова отобразить представление в случае ошибки. Это свойство никогда не публикуется, поэтому оно всегда будет нулевым внутри вашего действия POST, и когда представление будет отображено, помощник выдаст исключение:

[HttpPost]
public ActionResult Edit(EmployeesViewModel viewModel)
{
    //if editing an employee, fetch it; otherwise, create a new one
    Employee employee = GetEmployee(viewModel.EmployeeId);
    TryUpdateModel(employee);
    if (ModelState.IsValid)
    {              
        SaveEmployee(employee);
        TempData["message"] = "Employee has been saved.";
        return RedirectToAction("Details", new { id = employee.EmployeeID });
    }

    // Reload employee types from repository before redisplaying the view
    viewModel.EmployeeTypes = _adminRepository.GetAllEmployeeTypes();

    // validation error, so redisplay same view
    return View(viewModel);
}
0 голосов
/ 06 марта 2011

В EmployeesController.Edit(EmployeesViewModel viewModel) перед возвратом представления должна быть указана следующая строка:

 EmployeeTypes = _adminRepository.GetAllEmployeeTypes()

В вашем начальном EmployeesController.Edit(int id) вы делаете это, и оно появляется. Причина, по которой вам не нужно заполнять остальную часть модели представления, заключается в том, что их значения отправляются вместе с формой. Тем не менее, единственным значением для EmployeeType, который передается, является то, которое выбрано. Значения для представления должны исходить откуда-то, и вы не помещаете их нигде в этом действии контроллера.

Я не советую этого делать, но другой альтернативой было бы поместить массив типов сотрудников (разделенных запятыми) в скрытое поле ввода с именем EmployeeTypes в вашем представлении. быть представленным в модельном переплете. Лучше получить эти значения из базы данных.

код

    public ActionResult Edit(int id)
    {
        var employee = GetEmployee(id);
        if(employee == null)
        {
            TempData["message"] = "No employee exists with an ID of " + id + ", you can create a new employee here.";
            return RedirectToAction("Create");    
        }
        var viewModel = new EmployeesViewModel
        {
            EmployeeId = employee.EmployeeID,
            EmployeeTypeId = employee.EmployeeTypeID,
            Name = employee.Name
        };
        return EditEmployeeView(viewModel);
    }


    public ActionResult EditEmployeeView(EmployeesViewModel viewModel)
    {
        viewModel.EmployeeTypes = viewModel.EmployeeTypes ?? EmployeeTypes = _adminRepository.GetAllEmployeeTypes();
        return View(viewModel);
    }



    [HttpPost]
    public ActionResult Edit(EmployeesViewModel viewModel)
    {
        Employee employee = GetEmployee(viewModel.EmployeeId);
        TryUpdateModel(employee);
        if (ModelState.IsValid)
        {
            SaveEmployee(employee);
            TempData["message"] = "Employee has been saved.";
            return RedirectToAction("Details", new { id = employee.EmployeeID });
        }
        return EditEmployeeView(viewModel);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...