asp.net-mvc-3 – 在Post上,下拉列表SelectList.SelectedValue为null

我的模型如下:
public class testCreateModel
{
    public string s1 { get; set; }
    public SelectList DL { get; set; }

    public testCreateModel()
    {
        Dictionary<string,string> items = new Dictionary<string,string>();
        items.Add("1","Item 1");
        items.Add("2","Item 2");
        DL = new SelectList(items,"Key","Value");
    }
}

我的启动行动是:

public ActionResult testCreate()
    {
        testCreateModel model = new testCreateModel();
        return View(model);
    }

我的剃刀视图(删除了相关部分)是:

@model Tasks.Models.testCreateModel

@using (Html.BeginForm()) {
<fieldset>
    <legend>testCreateModel</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.s1)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.s1)
    </div>

    <div class="editor-label">
        Select an item:
    </div>
    <div class="editor-field">
        @Html.DropDownList("dropdownlist",(SelectList)Model.DL)
    </div>

    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>
}

回发行动是:

public ActionResult testCreate(testCreateModel model,FormCollection collection)
    {
        if (ModelState.IsValid)
        {
            Console.WriteLine("SelectedValue: ",model.DL.SelectedValue);
            Console.WriteLine("FormCollection:",collection["dropdownlist"]);
            // update database here...
        }
        return View(model);
    }

在回发后,model.DL.SelectedValue为null. (但是,可以从FormCollection中获取所选项目,但这不是重点). DL对象仍然正确填充,否则,立即窗口输出如下:

model.DL
{System.Web.Mvc.SelectList}
    base {System.Web.Mvc.MultiSelectList}: {System.Web.Mvc.SelectList}
    SelectedValue: null
model.DL.Items
Count = 2
    [0]: {[1,Item 1]}
    [1]: {[2,Item 2]}
model.DL.SelectedValue
null

Q1:如何使用SelectedValue属性

现在,如果在Razor视图中我将Html SELECT标记名称更改为DL(即与模型中的属性名称相同):

@Html.DropDownList("DL",(SelectList)Model.DL)

我得到一个例外:

No parameterless constructor defined for this object. 
Stack Trace: 
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type,Boolean publicOnly,Boolean noCheck,Boolean& canBeCached,RuntimeMethodHandleInternal& ctor,Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,Boolean skipVisibilityChecks,Boolean fillCache) +241
System.Activator.CreateInstance(Type type,Boolean nonPublic) +69
System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext,ModelBindingContext bindingContext,Type modelType) +199
System.Web.Mvc.DefaultModelBinder.BindSimpleModel(ControllerContext controllerContext,ValueProviderResult 
...

Q2:为什么?

谢谢.

解决方法

MVC将仅返回POST中所选选项的值,因此您需要一个属性来包含返回的单个值.

作为一个好建议,尝试通过ViewBag设置SelectLists,这有助于保持viewmodel不受需要填充表单的数据的影响.

所以你的例子可以像这样解决

public class testCreateModel
{
    public string s1 { get; set; }
    public int SelectedValue { get; set; }
}

并在您的视图中执行此操作:

@Html.DropDownList("SelectedValue",(SelectList)ViewBag.DL)

在您的GET操作中填充ViewBag.DL之前.

至于你的Q2,认的ModelBinder要求所有要绑定的类型都有一个认的构造函数(以便ModelBinder可以创建它们)

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....