SelectList при ошибке привязки модели страницы Razor - PullRequest
0 голосов
/ 02 марта 2019

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

InvalidOperationException: Could not create an instance of type 'Microsoft.AspNetCore.Mvc.Rendering.SelectList'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, set the 'SearchOptions' property to a non-null value

Вот код CS:

public class TestSelectModel : PageModel
{
    private List<SelectListItem> _searchoptions;
    [BindProperty(SupportsGet = true)]
    public SelectList SearchOptions { get; set; }
    public TestSelectModel()
    {
        _searchoptions = new List<SelectListItem>();
        _searchoptions.Add(new SelectListItem("By Email", "By Email", true));
        _searchoptions.Add(new SelectListItem("By Request Name", "By Request Name", false));
    }
    public void OnGet()
    {
        SearchOptions = new SelectList(_searchoptions, "Key", "Value", "By Email");

    }
}

А вот код cshtml:

<h2>TestSelect</h2>
<form>
    <div>
        <select asp-items="Model.SearchOptions">
            <option value="">Choose an search method</option>
        </select>
        <input type="submit" value="Filter" />
    </div>
</form>

У меня такое чувствоэто что-то легкое, но я просто не вижу этого.

EDIT

В комментарии также пробовал приведенный ниже код, который запускает функцию OnGet (), но выдает NullReferenceException: Object reference not set to an instance of an object.

private List<SelectListItem> _searchoptions;
public SelectList SearchOptions { get; set; }
[BindProperty(SupportsGet = true)]
public string BoundSearchField { get; set; }
public TestSelectModel()
{
    _searchoptions = new List<SelectListItem>();
    _searchoptions.Add(new SelectListItem("By Email", "By Email", true));
    _searchoptions.Add(new SelectListItem("By Request Name", "By Request Name", false));
}
public void OnGet()
{
    SearchOptions = new SelectList(_searchoptions, "Key", "Value", "By Email");
}


<form>
    <div>
        <select name="BoundSearchField" asp-items="Model.SearchOptions">
            <option value="">Choose an search method</option>
        </select>
        <input type="submit" value="Filter" />
    </div>
</form>

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Похоже, проблема была в том, как были определены SelectList и SelectListItems.В режиме отладки они выглядели нормально, но я думаю, что проблема была в том, когда рендеринг пытался произойти.Вот что сработало.Обратите внимание на изменение, когда я добавляю определения Text и Value для элементов, а затем копирую их при загрузке списка.Также обратите внимание, что мне пришлось использовать связанное поле, чтобы сохранить выбор пользователя после публикации.Мне действительно любопытно, как это не было нужно в примере Razor, на который я ссылался .

public TestSelectModel()
{
    _searchoptions = new List<SelectListItem>();
    _searchoptions.Add(new SelectListItem() { Text = "By Email", Value = "1", Selected = true });
    _searchoptions.Add(new SelectListItem() { Text = "By Request Name", Value = "2", Selected = false });
}
public void OnGet()
{
    if(BoundSearchField is null)
    {
        BoundSearchField = "1";
    }
    SearchOptions = new SelectList(_searchoptions, "Value", "Text", BoundSearchField);
}
0 голосов
/ 02 марта 2019

Ответ на исходный вопрос

Почему я получаю эту ошибку InvalidOperationException: Could not create an instance of type 'Microsoft.AspNetCore.Mvc.Rendering.SelectList'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, set the 'SearchOptions' property to a non-null value

Имеет атрибут BindProperty в свойстве SearchOptionsпопробуйте привязать данные заголовка к вашему SelectList.Удалите атрибут BindPropery из списка выбора и создайте свойство для получения выбранного значения.

Ответ на вопрос в вашем редактировании

Теперь я получаю ошибку NullReferenceException: Object reference not set to an instance of an object

Это потому, что "Key" должно быть "Text"

Изменить SearchOptions = new SelectList(_searchoptions, "Key", "Value", "By Email");
на SearchOptions = new SelectList(_searchoptions, "Text", "Value", "By Email");

Полный код:

private List<SelectListItem> _searchoptions;

// [BindProperty(SupportsGet = true)] // Remove this here
public SelectList SearchOptions { get; set; }

// Add a property to receive your selected value
[BindProperty(SupportsGet = true)]
public string BoundSearchField { get; set; }

public TestSelectModel()
{
    _searchoptions = new List<SelectListItem>();
    _searchoptions.Add(new SelectListItem("By Email", "By Email", true));
    _searchoptions.Add(new SelectListItem("By Request Name", "By Request Name", false));
}
public void OnGet()
{
    // Change "Key" to "Text"
    SearchOptions = new SelectList(_searchoptions, "Text", "Value", "By Email");
}

Затем добавьте name="BoundSearchField" к вашему .cshtml

<form>
    <div>
        <select name="BoundSearchField" asp-items="Model.SearchOptions">
            <option value="">Choose an search method</option>
        </select>
        <input type="submit" value="Filter" />
    </div>
</form>
...