C# Razor页面上的SelectList模型绑定错误

C# Razor页面上的SelectList模型绑定错误,c#,razor-pages,C#,Razor Pages,我试图按照示例代码进行操作,但我肯定遗漏了一些明显的东西。我没有从数据源读取选择列表选项,而是尝试将它们加载到构造函数中。但我一直在犯错误 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

我试图按照示例代码进行操作,但我肯定遗漏了一些明显的东西。我没有从数据源读取选择列表选项,而是尝试将它们加载到构造函数中。但我一直在犯错误

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");

    }
}

原问题的答案

为什么出现此错误
InvalidOperationException:无法创建类型为“Microsoft.AspNetCore.Mvc.Rendering.SelectList”的实例。模型绑定的复杂类型不能是抽象类型或值类型,并且必须具有无参数构造函数。或者,将“SearchOptions”属性设置为非空值

如果您的
SearchOptions
属性具有
BindProperty
属性,则将尝试将标题数据绑定到您的
SelectList
从选择列表中删除BindProperty属性,并创建一个属性来接收所选值。

编辑中问题的答案

现在我得到一个错误
NullReferenceException:objectreference未设置为对象的实例

是因为
“键”
应该是
“文本”

改变
SearchOptions=newselectlist(\u SearchOptions,“Key”,“Value”,“By Email”)
to
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");
}

问题似乎在于如何定义
SelectList
SelectList项目。在调试模式下,它们看起来很好,但我认为问题在于渲染尝试发生的时间。这就是成功的原因。注意,更改是我为项目添加
文本
定义,然后在加载列表时复制这些定义。还要注意的是,我必须使用绑定字段在发布后保存用户选择。我真的很好奇为什么在这个世界上不需要这些

publictestselectmodel()
{
_searchoptions=新列表();
_searchoptions.Add(新建SelectListItem(){Text=“By Email”,Value=“1”,Selected=true});
_添加(新的SelectListItem(){Text=“按请求名称”,Value=“2”,Selected=false});
}
公共互联网
{
如果(BoundSearchField为空)
{
BoundSearchField=“1”;
}
SearchOptions=新的选择列表(\u SearchOptions,“Value”,“Text”,BoundSearchField);
}

类似于
模型。SearchOptions
在渲染时为空。是否确实调用了
OnGet()
?无法调用它,因为模型绑定器正在尝试创建
SelectList
,并且由于没有默认构造函数而引发异常。@DavidTansey我可以确认没有调用
OnGet()
。如果我移动
SearchOptions=new SelectList(_SearchOptions,“Key”,“Value”,“By Email”)
进入构造函数时,会填充选择列表,但当我尝试使用
Count()
命令时,它会抛出
NullReferenceException
@杰瑞,很抱歉,我不同意你的建议。事实上,我很抱歉,我应该在我的答案中公布完整的代码。有两件事需要改变<代码>搜索选项=新建选择列表(_SearchOptions,“Key”,“Value”,“By Email”)实际上应该是
SearchOptions=newselectlist(_SearchOptions,“Text”,“Value”,“By Email”)。我将为您更新我的答案。这会引发以下错误:NullReferenceException:对象引用未设置为对象的实例。Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItemsWithValueField()您引用的示例包含
[BindProperty(SupportsGet=true)]公共字符串电影流派{get;set;}
以在发布后保存选择
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>
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");
}
<form>
    <div>
        <select name="BoundSearchField" asp-items="Model.SearchOptions">
            <option value="">Choose an search method</option>
        </select>
        <input type="submit" value="Filter" />
    </div>
</form>
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);
}