Как добавить пользовательский запрос для раскрывающегося списка и сохранить шаблон представления модели?
Я прочитал много статей, в которых утверждается, что запросы не должны помещаться в контроллер, но я не могу понять, где бы я их разместил.
Мой текущий код:
public class AddUserViewModel
{
public UserRoleType UserRoleType { get; set; }
public IEnumerable<SelectListItem> UserRoleTypes { get; set; }
}
public ActionResult AddUser()
{
AddUserViewModel model = new AddUserViewModel()
{
UserRoleTypes = db.UserRoleTypes.Select(userRoleType => new SelectListItem
{
Value = SqlFunctions.StringConvert((double)userRoleType.UserRoleTypeID).Trim(),
Text = userRoleType.UserRoleTypeName
})
};
return View(model);
}
Вид:
<li>@Html.Label("User Role")@Html.DropDownListFor(x => Model.UserRoleType.UserRoleTypeID, Model.UserRoleTypes)</li>
Как сохранить модель представления и запрос и исключить тип пользователя, который не должен отображаться?
2 ответа
Я думаю, что вы делаете это просто отлично.
В любом случае... все, что вы можете сделать, чтобы удалить логику запросов из контроллера, - это иметь ServiceLayer, где вы выполняете запрос и возвращаете результат.
Шаблон MVC здесь используется правильно... вам не хватает двух других уровней (BusinessLayer и DataAccessLayer)... поскольку ASP.NET MVC является уровнем пользовательского интерфейса.
ОБНОВЛЕНИЕ, из-за комментария:
С помощью var userroletypes = db.UserRoleTypes.Where(u=> u.UserRoleType != 1);
все в порядке, он вернет список UserRoleType, которые удовлетворяют запросу.
Затем просто создайте новый объект SelectList с использованием коллекции userroletypes... и присвойте его соответствующему свойству viewmodel. Затем передайте эту ViewModel в View.
Кстати, я никогда не использовал db.XXXX.Select()
метод раньше, не совсем уверен, что он делает... Я всегда использую Where
пункт.
ВТОРОЕ ОБНОВЛЕНИЕ: DropDownList загружается из SelectList, который является коллекцией SelectItems. Поэтому вам нужно преобразовать коллекцию, полученную в результате вашего запроса, в объект SelectList.
var userroletypes = new SelectList(db.UserRoleTypes.Where(u=> u.UserRoleType != 1), "idRoleType", "Name");
Затем вы создаете свою ViewModel
var addUserVM = new AddUserViewModel();
addUserVM.UserRoleTypes = userroletypes;
и передать addUserVM
на ваш взгляд:
return View(addUserVM );
Примечание: я предполагаю, что ваша ViewModel имеет свойство типа SelectList
... но ваш public IEnumerable<SelectListItem> UserRoleTypes { get; set; }
чтобы вы могли изменить его или адаптировать мой ответ.
Я не вижу ничего плохого в вашем коде, кроме этого db
Пример, который, как я полагаю, является конкретным EF-контекстом, который вы жестко закодировали в контроллере, что делает невозможным модульное тестирование изолированно. Ваше действие контроллера делает именно то, что делает обычное действие контроллера GET:
- запросить DAL, чтобы получить модель домена
- сопоставить модель домена с моделью представления
- передать модель представления в представление
Дальнейшее улучшение будет избавиться от UserRoleType
тип модели предметной области из вашей модели представления, делающий ее реальной моделью представления:
public class AddUserViewModel
{
[DisplayName("User Role")]
public string UserRoleTypeId { get; set; }
public IEnumerable<SelectListItem> UserRoleTypes { get; set; }
}
а потом:
public ActionResult AddUser()
{
var model = new AddUserViewModel()
{
UserRoleTypes = db.UserRoleTypes.Select(userRoleType => new SelectListItem
{
Value = SqlFunctions.StringConvert((double)userRoleType.UserRoleTypeID).Trim(),
Text = userRoleType.UserRoleTypeName
})
};
return View(model);
}
и в представлении:
@model AddUserViewModel
<li>
@Html.LabelFor(x => x.UserRoleTypeId)
@Html.DropDownListFor(x => x.UserRoleTypeId, Model.UserRoleTypes)
</li>