在ASP中用SelectList提交模型.净MVC

本文关键字:模型 MVC 提交 SelectList ASP 中用 | 更新日期: 2023-09-27 18:11:58

我所拥有的是一个具有多个输入的表单,我想用它来查询数据库中的一些结果。表单有一些默认值,它都工作,但我有问题提交给自己。

返回的错误是"No parameter constructor defined for this object",这是由SelectList object引起的。

我已经尝试了这个解决方案,并使psUserType私有getter和setter,并将其初始化为空列表,但随后我的下拉菜单在开始时没有值。不知道为什么GetUserTypes没有填充它们

我在这里做错了什么?如何既具有预选值,又发送具有用户选择值的相同模型,同时还在同一页面上显示结果?

对所有3种操作使用相同的模型有意义吗?使用默认值显示表单和输入。提交期间提交所选值。返回结果和选择的值?我也读过这个解决方案,但不确定如何在这里使用2或3个单独的模型。

任何帮助都是感激的。提前谢谢。

public class SearchDownloadsModel
{
    public SelectList psUserType { get; private set; } //causes problem on submit
    public string psText { get; set; }
    public MultiSelectList psColumns { get; private set; }
    public IEnumerable<ResultsRowModel> psResults { get; set; }
    public SearchDownloadsModel()
    {            
        this.psUserType = GetUserTypes();          
        this.psColumns = GetColumns();
        this.psResults = new List<ResultsRowModel>(); //empty by default
    }
    public SelectList GetUserTypes()
    {
        List<SelectListItem> items = new List<SelectListItem>()
        {
            new SelectListItem { Value="user", Text="Single User" },
            new SelectListItem { Value="group", Text="User group" },
            ...               
        };
        return new SelectList(items, "Value", "Text");
    }
    public MultiSelectList GetColumns()
    {
        List<SelectListItem> items = new List<SelectListItem>()
        {
            new SelectListItem { Value = "user", Text="Username" },
            new SelectListItem { Value = "file", Text="Filename" },
            new SelectListItem { Value = "titl", Text="Title" },
            new SelectListItem { Value = "auth", Text="Author" },
            ...
        };
        return new MultiSelectList(items, "Value", "Text");
    }
}
public class ResultsRowModel
{
    public int ID { get; set; }
    public string EventTime { get; set; }
    public string FileName { get; set; }
    public string FilePath { get; set; }
    public string UserName { get; set; }
    ...
}
<<p> 视图/strong>
@model Proj.Models.SearchDownloadsModel
@using (Html.BeginForm("Downloads", "Home", FormMethod.Post))
{
   @Html.DropDownListFor(x => x.psUserType, Model.psUserType)
   @Html.TextBoxFor(x => x.psText)
   @Html.ListBoxFor(x => x.psColumnsSelected, Model.psColumns, new { multiple = "multiple" })
   <button type="submit" class="btn btn-primary">Search</button>
}
@if (Model.psResults != null && Model.psResults.Any())
{
    <table>
        <tr>
            <th>User</th>
            <th>File</th>
        </tr>
        @foreach (var row in Model.psResults)
        {
            <tr>
                <td>@row.UserName</td>
                <td>@row.FileName</td>
            </tr>
        }
    </table>
}
控制器

[HttpGet]
public ActionResult Downloads()
{
    SearchDownloadsModel model = new SearchDownloadsModel();
    model.psColumnsSelected = new List<string>() { "user", "file" }; //preselected values
    return View(model);
}
[HttpPost]
public ActionResult Downloads(SearchDownloadsModel model)
{       
    model.psResults = queryDatabase(model);
    return View(model);
}
private List<ResultsRowModel> queryDatabase(SearchDownloadsModel model)
{
    //...
}

编辑:在SearchDownloadsModel下添加ResultsRowModel

在ASP中用SelectList提交模型.净MVC

NET MVC中,你应该只把包含提交或选择值的变量放在ViewModel类中。选择列表项被认为是额外的信息,通常使用ViewBag项从动作方法传递到视图(.cshtml)。

许多呈现扩展方法甚至是专门为这种方法编写的,导致如下代码:

控制器

ViewBag.PersonID = persons.ToSelectList(); // generate SelectList here
<<p> 视图/strong>
@Html.DropDownListFor(model => model.PersonID)
@* The above will look for ViewBag.PersonID, based on the name of the model item *@

DropDownListFor生成一个<select>元素,该元素带有您绑定它的属性名称。当您提交表单时,该名称将作为表单字段之一包含,其值将是您选择的选项值。

您将DropDownList绑定到类型SelectList (psUserType)的属性,并且当您的操作被调用时,必须创建SelectList的新实例以便将表单字段绑定到它。首先,SelectList类没有无参数构造函数,因此,您的错误。其次,即使SelectList可以作为模型绑定的一部分创建,<select>元素提交的是一个字符串值,无论如何都不能转换为SelectList

你需要做的是添加string属性到你的SearchDownloadsModel,例如:

public string SelectedUserType { get; set; }

然后将下拉列表绑定到这个属性:

@Html.DropDownListFor(x => x.SelectedUserType, Model.psUserType)

当您提交表单时,这个新属性将具有您在下拉列表中选择的值。

Peter的回答和Stephen的评论帮助我解决了这个问题。
也许有人会觉得它有用。

欢迎任何进一步的建议。

public class PobraniaSzukajModel
{
    public IEnumerable<SelectListItem> UserTypes { get; set; }
    public string psSelectedUserType { get; set; }
    public IEnumerable<SelectListItem> Columns { get; set; }
    public IEnumerable<string> psSelectedColumns { get; set; }
    public string psText { get; set; }
    public ResultsModel psResults { get; set; }
}
<<p> 视图/strong>
@Html.ListBoxFor(x => x.psSelectedUserType, Model.Columns)
@Html.TextBoxFor(x => x.psText)
@Html.ListBoxFor(x => x.psSelectedColumns, Model.Columns)
控制器

[HttpGet]
public ActionResult Downloads()
{    
    SearchDownloadsModelmodel = new SearchDownloadsModel();  
    model.UserTypes = GetUserTypes();
    model.Columns = GetColumns();     
    model.psColumnsSelected = new List<string>() { "user", "file" }; //preselected values
    return View(model);
}
[HttpPost]
public ActionResult Downloads(SearchDownloadsModel model)
{
    model.UserTypes = GetUserTypes();
    model.Columns = GetColumns();     
    model.psResults = GetResults(model);
    return View(model);
}
public SelectList GetUserTypes()
{
    //...
}
public MultiSelectList GetColumns()
{
    //...
}
public ResultsModel GetResults()
{
    //...
}