我的 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)
在回答您的第一个问题时,您应该在表单标签中包含回发(表单提交)所需的所有数据
标签之外的任何内容都不会包含在帖子数据中
有一个 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>
来表示您可选择的数据,或者您可能只想创建一个显式类