MVC4:模型的属性为空

问题描述 投票:0回答:1

我的 MVC4 应用程序有一个列表框和几个按钮。当我在 ListBox 中选择一个项目并按下 Delete 按钮并命中 Delete() 方法中的断点时,出于某种原因,传递给 Delete() 方法的模型对象的所有属性都为空。这是为什么?

这里是一些代码:

在模型中:

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)
asp.net-mvc-4 c#-4.0
1个回答
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>
来表示您可选择的数据,或者您可能只想创建一个显式类

© www.soinside.com 2019 - 2024. All rights reserved.