2009-09-03 5 views
0

Это то, что мои классы модели данных выглядит следующим образом:Два источника данных в одном создать вид

public class Employee 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public Position Position { get; set; } 
} 

public class Position 
{ 
    public string Title { get; set; } 
} 

У меня есть создать представление, где я хочу иметь два текстовых поля для имени и фамилии, а затем который имеет название позиции. Я пытался делать это так:

View (только соответствующая часть):

<p> 
    <label for="Position">Position:</label> 
    <%= Html.DropDownList("Positions") %> 
</p> 

Контроллер:

// 
// GET: /Employees/Create 

public ActionResult Create() 
{ 
    ViewData["Positions"] = new SelectList(from p in _positions.GetAllPositions() select p.Title); 

    return View(); 
} 

// 
// POST: /Employees/Create 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Employee employeeToAdd) 
{ 
    try 
    { 
     employeeToAdd.Position = new Position {Title = (string)ViewData["Positions"]}; 
     _employees.AddEmployee(employeeToAdd); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

Однако, когда я нажимаю отправить, я получаю это исключение:

System.InvalidOperationException was unhandled by user code 
Message="There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'Positions'." 

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

ответ

0

Я считаю, что ViewData предназначен для передачи информации в ваш вид, но она не работает в обратном порядке. То есть ViewData не будет установлен с Request.Form. Я думаю, вы можете изменить свой код следующим образом:

// change following 
employeeToAdd.Position = new Position {Title = (string)ViewData["Positions"]}; 
// to this? 
employeeToAdd.Position = new Position {Title = (string)Request.Form["Positions"]}; 

Удачи вам!

+0

P.S. вам не хватает 's' в вашей'

+0

Что такое атрибут for? –

+0

он должен соответствовать этикетке с вводом. Это для большей доступности, например, для людей, использующих экранные считыватели, чтобы они знали, что они должны заполнять. Произошло ли изменение, которое я предложил? – Funka

1

В службе Create() (WITH POST ATTRIBUTE), так как ViewData ["Positions"] не установлен, вы получаете эту ошибку. Это значение должно составлять часть вашего запроса на отправку и после перезаписи после того, как сообщение должно получить его из хранилища или получить его из сеанса/кеша, если вам нужно переподтвердить это.

Запомнить ViewData доступен только для текущего запроса, поэтому для post request ViewData ["Positions"] еще не создан и, следовательно, это исключение.

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

// add the required namespace for the model... 
protected override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    // add your logic to populate positions here... 
    ViewData["Positions"] = new SelectList(from p in _positions.GetAllPositions() select p.Title); 

} 

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

3

Вы можете хранить:

(string)ViewData["Positions"]}; 

в hiddn метки на странице, то назвать это как этот

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Employee employeeToAdd, string Positions) 
{ 
+0

Хмм, хранение вещей в скрытых полях звучит как нечто из Webforms. Нет ли лучшего способа сделать это? Он может работать только для одного или двух полей, но представьте, если у вас есть форма с 15 различными полями, которые получают данные из модели данных. Это было бы очень уродливо. –

+0

Я думаю, что метод действия выглядит великолепно, но я не считаю, что скрытый вход должен быть необходим. 'string Positions' должен автоматически привязываться к вам в зависимости от того, что было выбрано в Dropbox. – Funka

Смежные вопросы