dropdownlist для неправильного типа [дубликат]

Вот несколько способов доступа к родительскому контексту внутри дочернего контекста -
  1. Вы можете использовать функцию bind().
  2. Хранить ссылку на контекст / внутри внутри другой переменной (см. пример ниже).
  3. Использовать функции ES6 Arrow .
  4. Изменить код / function design / architecture - для этого вы должны иметь команду над шаблонами проектирования в javascript.

1. Используйте функцию bind()

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', ( function () {
        alert(this.data);
    }).bind(this) );
}
// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};
// called as
var obj = new MyConstructor('foo', transport);

Если вы используете underscore.js - http://underscorejs.org/#bind

transport.on('data', _.bind(function () {
    alert(this.data);
}, this));

2 Сохраните ссылку на контекст / внутри внутри другой переменной

function MyConstructor(data, transport) {
  var self = this;
  this.data = data;
  transport.on('data', function() {
    alert(self.data);
  });
}

3 Функция стрелки

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}
68
задан Stephen Muecke 19 December 2015 в 02:26
поделиться

1 ответ

Ошибка означает, что значение CategoryList равно нулю (и в результате метод DropDownListFor() ожидает, что первый параметр имеет тип IEnumerable<SelectListItem>).

Вы не генерируете вход для каждого свойства каждого SelectListItem в CategoryList (и не должен), поэтому никакие значения для SelectList не отправляются в метод контроллера, и поэтому значение model.CategoryList в методе POST равно null , Если вы вернете представление, вы должны сначала переназначить значение CategoryList, как и в методе GET.

public ActionResult Create(ProjectVM model)
{
    if (!ModelState.IsValid)
    {
        model.CategoryList = new SelectList(db.Categories, "ID", "Name"); // add this
        return View(model);
    }
    // Save and redirect
}

Чтобы объяснить внутреннюю работу (исходный код может быть см. здесь )

Каждая перегрузка DropDownList() и DropDownListFor() в конечном итоге вызывает следующий метод

private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
  string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
  IDictionary<string, object> htmlAttributes)

, который проверяет, есть ли selectList (второй параметр из @Html.DropDownListFor()) является null

// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
    selectList = htmlHelper.GetSelectData(name);
    usedViewData = true;
}

, который, в свою очередь, вызывает

private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)

, который оценивает первый параметр @Html.DropDownListFor() (в данном случае CategoryID )

....
o = htmlHelper.ViewData.Eval(name);
....
IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
if (selectList == null)
{
    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
        MvcResources.HtmlHelper_WrongSelectDataType,
        name, o.GetType().FullName, "IEnumerable<SelectListItem>"));
}

Поскольку свойство CategoryID является typeof int, оно не может быть передано в IEnumerable<SelectListItem>, и генерируется исключение (которое определено в файле MvcResources.resx как)

<data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
    <value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
</data>
65
ответ дан Stephen Muecke 21 August 2018 в 23:29
поделиться
  • 1
    @Shyju, Да, я спросил и ответил на это (как сообщество wiki) исключительно для целей обманывания многих других подобных вопросов о SO, которые остаются без ответа или неприняты. Но я вижу, что избиратели мести уже начали - первое было меньше 2 секунд после публикации - недостаточно времени, чтобы даже прочитать его, не говоря уже о ответе. – Stephen Muecke 19 December 2015 в 02:49
  • 2
    Понимаю. Есть 100 вопросов с той же проблемой. Обычно люди, которые задают эти вопросы, не выполняют надлежащего поиска (или они скопировали и вставили существующий ответ слово за словом, но не сработали!) Поэтому я не уверен, что это может действительно помочь. :) Красиво написано BTW. – Shyju 19 December 2015 в 03:15
  • 3
    @Stephen это не так, как вы спрашиваете, и вы отвечаете – Dilip 19 December 2015 в 06:45
  • 4
    @DilipN, Что значит не правильный путь ? Его фактически поощряли к SO. Вы должны прочитать этот и потратить некоторое время на мета. – Stephen Muecke 19 December 2015 в 06:46
  • 5
    @DilipN, потому что я буду использовать его, чтобы отметить множество подобных вопросов, как дубликатов, которые либо остались без ответа, либо ответили, но не приняты, поэтому их можно закрыть (и, следовательно, другие не тратят впустую свое время). Я также сделал это сообщество wiki, чтобы каждый мог редактировать и улучшать его с течением времени. – Stephen Muecke 19 December 2015 в 06:54
Другие вопросы по тегам:

Похожие вопросы: