Создание пользовательского помощника MVC 3, в котором используются выражения типа DropDownListFor - PullRequest
1 голос
/ 15 февраля 2012

Что я хочу для вывода HTML

<select name="model binding name"> 
 <option value="44" data-object="jsonencoded object">122 front street</option>
 <option value="45" data-object="jsonencoded object">123 main street</option>
<select>

Строка в моем файле cshtml будет выглядеть как

@Html.DropDownFillerFor(model => model.ProfileAddressId, 
((ProfileUser)ViewData["ProfileData"]).Addresses, 
profileAddress => profileAddress.AddressID.ToString(CultureInfo.InvariantCulture),
profileAddress => profileAddress.House + " " + profileAddress.Street)

Эта модель похожа на оформление заказа в магазине, и вы должны выбратьадрес для использования из коллекции адресов в ProfileData.

Моя проблема в том, чтобы понять, как ViewData работает внутри помощников, и я читаю источник MVC 3.

Мое первоначальное решение было:

public static MvcHtmlString DropDownFillerFor<TModel, TProperty, T2Model>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<T2Model> objectList,
Expression<Func<T2Model, string>> valueExp,
Expression<Func<T2Model, string>> textExp,
IDictionary<string, object> htmlAttributes = null)
        {
 var textFunc = textExp.Compile();
            var valueFunc = valueExp.Compile();
foreach (var o in objectList)
            {
                var sli = new SelectListItem {Text = textFunc(o), Value = valueFunc(o)};
                selectList.Add(sli);
            }
            return htmlHelper.DropDownListFor(expression, selectList, null, null);
}

И это было здорово, но не хватало возможности добавлять настраиваемые атрибуты html для каждой опции.К сожалению, все методы, которые использует DropDownListFor, являются закрытыми, поэтому я пытаюсь использовать их код (при условии, что они знают об этом больше, чем я).Я работаю над кодом для SelectInternal, который находится в классе SelectExtensions, и я получаю строку:

object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));

Эта строка, кажется, получает значение из модели, поэтому в моем случае значениеmodel => model.ProfileAddressId, но я не могу найти способ воспроизвести это в моем коде.

Функция GetModelStateValue в основном возвращает значение в ViewData.ModelState.TryGetValue (key, out modelState).Пройдя еще несколько уровней вверх по линии, я обнаружил, что все это ссылается на «IViewDataContainer ViewDataContainer».Это заполняется, когда htmlhelper создается с помощью «HtmlHelper MakeHtmlHelper (HtmlHelper html, iewDataDictionary viewData)», и я могу подняться еще на несколько уровней, но это то место, где я его теряю.

Мой вопрос.Как получить значения из модели при написании метода расширения?

1 Ответ

0 голосов
/ 23 февраля 2012

Редактировать: Код для моего решения опубликован на http://pastebin.com/r912xtat Прошло много времени, поэтому я не помню деталей, но спрашиваю и могу попытаться помочь.

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