Как добавить пользовательский запрос для раскрывающегося списка и сохранить шаблон представления модели?

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

Мой текущий код:

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:

  1. запросить DAL, чтобы получить модель домена
  2. сопоставить модель домена с моделью представления
  3. передать модель представления в представление

Дальнейшее улучшение будет избавиться от 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>
Другие вопросы по тегам