繁体   English   中英

在ASP.NET MVC中从View传递模型到Controller

[英]Passing Model to Controller from View in ASP.NET MVC

我正在研究我在ASP.NET MVC中的第一个应用程序,并且遇到了一个我无法弄清楚的障碍,即使在阅读整个互联网之后。

所以我有几个使用View Models创建的视图(它们是报告),它们是根据用户选择标准填充的。 我正在尝试构建一个接受模型并以Excel格式导出它的方法(使用EPPlus),但模型需要从其中一个视图发送。 这在某种程度上是功能/可用性,而不是技术要求。 用户可以运行报告,查看报告后,可以单击按钮/链接,将创建他们正在查看的报告的Excel版本。 我想传递正在显示的视图所基于的模型,因为已经完成了根据用户的报告选择标准构建此特定视图模型的工作。

这一切都很好,我可以成功地将一个模型从显示报告的视图传递给构建报告的方法。 View Model I中的所有数据似乎都在那里,除了作为其一部分的Models(IEnumerable)集合。 < - 这就是我被困住的地方。 IEnumerable的集合在断点处有0个项目,但在创建视图模型并最初传递到View时绝对不是这种情况。

我被困了 - 请帮忙。

查看型号:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM