MVC4:模型的属性为null

时间:2014-05-14 13:43:26

标签: asp.net-mvc-4 c#-4.0

我的MVC4应用程序有一个ListBox和几个按钮。当我在ListBox中选择一个项目并按下Delete按钮并在Delete()方法中点击断点时,由于某种原因,传递给Delete()方法的模型对象的所有属性都为null。你能解释一下吗?

以下是一些代码:

在模型中:

public class EdiFileModel
{
    public SelectList EdiFileNames { get; set; }
    public string SelectedEdiFilename { get; set; }
...
}

在视图中:

@model EdiSimulatorWebSender.Models.EdiFileModel
...

@Html.ListBoxFor(m => m.SelectedEdiFilename, new SelectList(Model.EdiFileNames, "Value", "Text", Model.EdiFileNames.SelectedValue), new { @Id = "EdiFileNames", @style = "width:Auto;height=Auto;maxHeight:200;" })

<form action="" method="post">
 <input type="submit" value="Send" name="action:Send" />
 <input type="submit" value="Delete" name="action:Delete" />
 <input type="submit" value="Refresh" name="action:Refresh" />
</form>

在控制器中:

    [HttpPost]
    [MultipleButton(Name = "action", Argument = "Delete")]
    [ActionName("Index")]
    public ActionResult Delete(EdiFileModel ediFileModel)
    {
        string selectedFileName = ediFileModel.SelectedEdiFilename;
        ...
    }

增加:

我还希望能够不仅回复所选项目的ID,而且还有列表本身,以便我可以使用Id来获取所选项目。在我的例子中,ListBox包含特定文件夹中文件的名称。我希望能够选择文件,按“删除”按钮并删除文件。在Delete()方法中,我得到了Id,但我想得到EdiFileNames。

这是我的最新代码:

型号:

public class EdiFileModel
{
    //public SelectList EdiFileNames { get; set; }
    public Dictionary<string, string> EdiFileNames { get; set; }
    public string SelectedEdiFileId { get; set; }
    public string ResponseContent { get; set; }
}

控制器:

    public ActionResult Index()
    {
        var ediFileModel = new EdiFileModel {EdiFileNames = GetAllEdiFiles()};
        return View(ediFileModel);
    }

    [HttpPost]
    [MultipleButton(Name = "action", Argument = "Delete")]
    [ActionName("Index")]
    public ActionResult Delete(EdiFileModel ediFileModel)
    {
        string selectedFileId = ediFileModel.SelectedEdiFileId;

        string selectedFileFullName = Path.Combine(SourcePath, ediFileModel.EdiFileNames[selectedFileId]);
        System.IO.File.Delete(selectedFileFullName);            
        return View(ediFileModel);
    }

查看:

@using (Html.BeginForm())
{
    var ediFilesSelectList = new SelectList(Model.EdiFileNames, "Key", "Value", Model.SelectedEdiFileId);
    @Html.ListBoxFor(m => m.SelectedEdiFileId, ediFilesSelectList, new {@Id = "EdiFileNames", @style = "width:Auto;height=Auto;maxHeight:200;"})
    @Html.HiddenFor(model => model.EdiFileNames)

1 个答案:

答案 0 :(得分:0)

在回答您的第一个问题时,您应该在表单标记中包含回发(表单子表单)中所需的所有数据

标签之外的任何内容都不会作为发布数据的一部分包含在内

你可以使用一个MVC帮助程序,这样可以很容易:

@using(Html.BeginForm("x/y/z")) 
{ 
  // Html/Razor for your controls/inputs here
}

您还需要在回发中包含您要发送回模型的任何数据 - 如果您不包含它,它就不会在那里。您可以在回发方案中获取数据(在控制器操作上),也可以通过将其包含在表单中将其传回后期数据中。

如果要将其从用户视图中隐藏,可以将其设为隐藏元素:

@Html.HiddenFor(m => m.SomeProperty)

您遇到的第二个问题是模型绑定器使用反射来创建模型类型的实例,以便从后期数据中重新水化模型。

可在此处阅读完整详情:http://msdn.microsoft.com/en-us/magazine/hh781022.aspx

这意味着您作为模型一部分使用的任何类型都需要具有无参数构造函数,以便模型绑定器创建实例并注入后期数据。

您在模型上使用SelectList,它没有无参数构造函数,实际上只应用于表示视图中可选择的项目列表。模型绑定器无法实例化空SelectList以填充帖子数据,因此会抛出观察到的错误

为了使其工作,您应该使用具有无参数构造函数的另一种类型,或者创建包含所需字段的自己的类型。您可以使用KeyValuePair<K,V>来表示可选择的数据,或者您可能只想创建一个显式类

相关问题