将模型从视图传递给控制器净MVC
本文关键字:控制器 MVC 模型 视图 | 更新日期: 2023-09-27 18:08:46
我正在开发我的第一个ASP应用程序。. NET MVC和遇到了一个障碍,我不能弄清楚,甚至在阅读整个互联网之后。
所以我有几个视图(它们是报告),这些视图是用视图模型创建的,它们是根据用户选择标准填充的。我试图建立一个方法,接受一个模型,并导出它在Excel格式(使用EPPlus),但模型需要从这些视图之一发送。这在某种程度上是功能/可用性要求,而不是技术要求。用户可以运行报表,在查看报表后,可以单击按钮/链接,然后将创建他们正在查看的报表的Excel版本。我想传递正在显示的视图所基于的模型,因为已经根据用户的报表选择标准构建了这个特定的视图模型。
这一切都很好,我可以成功地将显示报告的视图中的模型传递给构建报告的方法。我传递的视图模型中的所有数据似乎都在那里,除了模型(IEnumerable)的集合是它的一部分。<——这就是我被困住的地方。IEnumerable的集合在断点处有0个项目,但是当创建视图模型并最初传递给视图时,绝对不是这种情况。
我卡住了,请帮忙。
View Model:
public class ReportViewModel
{
public int ProjectId { get; set; }
[Display(Name = "Project Name")]
public string ProjectName { get; set; }
[Display(Name = "Project #")]
public string ProjectNumber { get; set; }
public IEnumerable<SystemModel> SelectedSystems { get; set; }//has items when created and passed into the View intially, but not when the Model is passed from the View to the method/controller.
[Display(Name = "All Systems")]
public bool AllSystems { get; set; }
[Display(Name = "In Progress Systems")]
public bool InProgressSystems { get; set; }
[Display(Name = "Completed Systems")]
public bool CompletedSystems { get; set; }
[Display(Name = "Unchecked Systems")]
public bool UncheckedSystems { get; set; }
[Display(Name = "Systems with Problems - Ours")]
public bool JciIssue { get; set; }
[Display(Name = "Systems with Problems - Other's")]
public bool OtherIssue { get; set; }
[Display(Name = "Include Points with Problems")]
public bool IncludePoints { get; set; }
}
视图:
@model ProjectOps_5.ViewModels.ReportViewModel
@{
ViewBag.Title = "Software Cx Status Report";
}
<h2>Software Cx Status Report</h2>
<div>
<div>
<hr />
@Html.ActionLink("Export to Excel", "ExportExcel", Model)//call to method
//the report
方法:
public void ExportExcel(ReportViewModel model)
{
//make Excel file
}
您不能将包含复杂对象或集合属性的模型传递给GET。在内部,ActionLink()
方法调用每个属性的.ToString()
方法,所以基本上DefaultModelBinder
试图将属性设置为如下所示
model.SelectedSystems = "System.Collections.Generic.IEnumerable<SystemModel>";
当然失败了,属性是null
。
幸运的是,它不起作用,否则您将生成一个非常难看的查询字符串,并且很容易超过查询字符串限制并抛出异常。
相反,传递ProjectId
属性(我假设唯一标识对象)并在ExportExcel()
方法中再次获得模型
@Html.ActionLink("Export to Excel", "ExportExcel", new { ID = Model.ProjectId })
和控制器
public void ExportExcel(int ID)
{
// Get your ReportViewModel based on the ID and do stuff
}
将整个视图模型传递给另一个方法可能不是最好的主意,因为您不知道模型的大小(SelectedSystems
中的元素数量)。如果它太大,您可能超过最大请求长度或使用户等待太长时间,直到请求完成。
但如果你绝对确定这是你需要的-它可以使用一个形式:
@using (Html.BeginForm("ExportExcel", null, FormMethod.Post))
{
@Html.Hidden("ProjectId", Model.ProjectId)
@Html.Hidden("ProjectName", Model.ProjectName)
...
@for(int i = 0; i < Model.SelectedSystems.Count(); i++)
{
var systemModel = Model.SelectedSystems.ElementAt(i);
@Html.Hidden("SelectedSystems[" + i + "].Property1", systemModel.Property1)
@Html.Hidden("SelectedSystems[" + i + "].Property2", systemModel.Property2)
}
<input type="submit" value="Export to Excel" />
}
但是,更好的方法是使用您想要导出的所有对象的一些标识符(不确定它们在您的情况下可能是什么),并将这些id作为ActionLink
路由值传递。
您可以尝试以下逻辑,您必须在发送请求之前做(或取决于您的页面,但它应该在发送请求之前可用)
var html = "";
for (index = 0; index < SelectedSystems.length; index++) {
html += '<input type="hidden" name="SelectedSystems[' + index + '].PropertyName" id="SelectedSystems _' + index + '_PropertyName" value="YourValue"/>';
}
$("#divSelectedSystems").html(html); //Here divSelectedSystems is one dummy div with that id