Попытка использовать DropDownListFor без дерева получения модели может не содержать ошибку динамической операции

Я пытаюсь использовать DropDownListFor<> в своем LayoutTemple, поэтому у меня нет доступа к модели. Итак, что я сделал, так это в блоке @{} в верхней части страницы я добавил FFInfo.DAL.SoloClassesContext db = new FFInfo.DAL.SoloClassesContext();, который вызывает экземпляр DBContext с классом, который я хочу использовать. Затем я разместил список там, где хотел использовать

@Html.DropDownListFor(
m => m.ID,
new SelectList(db.CultureCodes, "ID", "DisplayName"));

но когда я запускаю код, я получаю сообщение об ошибке для строки m => m.ID. Указана ошибка:

Дерево выражения не может содержать динамическую операцию

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


person Community    schedule 13.10.2013    source источник
comment
Наличие вашего контекста в ваших ПРОСМОТРАХ выглядит очень, очень, очень плохой идеей ... сохраняйте представления глупыми, насколько это возможно. Выполнение вызовов в БД - это работа контроллера.   -  person Raphaël Althaus    schedule 13.10.2013
comment
Это НЕ вид, это ШАБЛОН МАКЕТА.   -  person    schedule 13.10.2013


Ответы (1)


Я предлагаю некоторые изменения в вашем решении:

  1. Вместо DropDownListFor() используйте только DropDownList()

    @Html.DropDownList(CultureCode, новый SelectList(db.CultureCodes, ID, DisplayName))

  2. Вместо доступа к данным вашей базы данных в вашем представлении... что очень не соответствует стандарту, и вы связываете представления (обычно HTML) с базой данных... вы должны поместить запрос в свой контроллер и поместить данные в ViewBag коллекция.

Итак, в вашем макете вместо кода, который я предложил выше, вы должны использовать:

 @Html.DropDownList("CultureCode", (SelectList)ViewBag.Codes, "Select one...")

В вашем контроллере вы загружаете его следующим образом:

 ViewBag.Codes = new SelectList(db.CultureCodes, "ID", "DisplayName");

EDIT: вы можете сделать фильтр действий, чтобы загрузить или внедрить CultureCodes в ViewBag:

public class IncludeCultureCodesAttribute : ActionFilterAttribute
{
        public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var controller = filterContext.Controller;

        // IController is not necessarily a Controller
        if (controller != null)
        {
            var db = new YourContext();
            controller.ViewBag.Codes = new SelectList(db.CultureCodes, "ID", "DisplayName"));;
        }
    }
}

Затем в действиях контроллера... вы можете украсить их [IncludeCultureCodes]. Таким образом, действие с этим атрибутом загрузит коллекцию кодов.

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

person Romias    schedule 13.10.2013
comment
Это делается в файле _Layout.cshtml, поэтому контроллера нет, если только вы не предлагаете мне добавлять код вызова для каждого отдельного контроллера, который я делаю, чтобы передать его в файл макета? - person ; 13.10.2013