【问题标题】:MVC3 Pass viewmodel object with Iqueryable back to ControllerMVC3 将带有 Iqueryable 的视图模型对象传递回控制器
【发布时间】:2011-11-22 04:10:58
【问题描述】:

我有一个视图,我将一个 viewmodel 对象传递给它,其中包含一个 IQueryable 对象。

此对象用于填充 mvccontrib 网格。该视图还包含其他部分视图,允许用户过滤网格中的数据。

一旦网格被过滤,我希望用户能够将 Iqueryable 对象导出到另一个控制器 actionresult 方法,然后调用另一个视图模型将数据导出到 Excel。

这里是调用Export actionresult()方法的视图的sn-p:

@using (Html.BeginForm("Export", "Home", FormMethod.Post, new { Model }))
{
  <p>
   <input class="button" value="Export to Excel" type="submit" />
  </p>

}

模型确实包含 IQueryable 对象。

当我调试代码时,我可以查看视图模型对象,当然,为了填充 IQueryable,我必须枚举该对象。

我还创建了另一个 viewmodel 对象,一旦将 Model 对象传递回 actionresult 方法,它就会尝试使用 .ToList() 方法或 AsEnumerable() 方法枚举 IQueryable 对象。

但在所有情况下,IQueryable 对象都会作为空对象传递给控制器​​。

这是从视图中调用的动作结果方法:

[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Export(PagedViewModel<NPSProcessed> NPSData)
{
    string message = "";
    NPSData Query = new Models.NPSData(NPSData);

    Query.IData = NPSData.Query.ToList();

        // Opening the Excel template...
        FileStream fs =
        new FileStream(Server.MapPath(@"\Content\NPSProcessedTemplate.xls"),         FileMode.Open, FileAccess.Read);

        MemoryStream ms = new MemoryStream();

        ee.ExportData(fs, ms, Query.IData, message);

        // Sending the server processed data back to the user computer...
        return File(ms.ToArray(), "application/vnd.ms-excel", "NPSProcessedNewFile.xls"); 

    }

任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: c# asp.net-mvc-3 viewmodel


    【解决方案1】:

    您不能像这样传递复杂的对象:new { Model }。这本来很容易:-)。您必须一一发送:

    new { prop1 = Model.Prop1, prop2 = Model.Prop2, ... }
    

    显然,这可能会很痛苦。所以我建议你只发送一个 id:

    new { id = Model.id }
    

    然后在应该导出到 Excel 的控制器操作中使用此 id 从您最初在 GET 操作中获取的任何位置(可能是数据库或其他东西)获取对象。如果您想保留分页以及用户可以在网格上执行的操作,您也可以将它们发送到服务器:

    new { id = Model.id, page = Model.CurrentPage, sortColumn = Model.SortBy }
    

    另一种可能性(我不推荐)是将这个对象保存到会话中,以便您以后可以取回它。

    另一种可能性(我仍然不推荐)是使用 MVCContrib 的 Html.Serialize 帮助器,它允许您将整个对象图序列化为隐藏字段,并在提交表单时将其发送到服务器并且您将能够获取它作为操作参数。

    【讨论】:

    • 好答案,我试过新的 {prop1 = Model.Query}。 Model.Query 是 IQueryable 对象。我收到以下错误:无法创建接口的实例。
    • @Joe Pitz,不,只有简单类型(字符串、整数等)。不要尝试发送任何复杂的对象。它不会起作用。
    • 如果用户选择了几百行,那么将这些数据传回模型的最佳方式是什么。传递用户选择的过滤参数,然后在导出模型中使用这些参数在数据表上重新创建过滤条件是最好的方法吗?谢谢
    • @Joe Pitz,只传递那些选定行的 ID。然后在服务器上使用这些 id 从数据存储中获取相应的数据。
    • 作为测试,我尝试将字符串作为 new {prop1 = "test"} 传递,但 actionresult 仍然看到一个空值。这个视图包含几个 {Html.RenderPartial();} 方法。在其中一个部分视图中,还有一个 using (Html.BeginForm("Index", "Home", FormMethod.Get))。这可能是问题的一部分吗?如果是这样我该如何解决,谢谢所有的帮助。乔
    【解决方案2】:

    简单的答案是:不要将 IQueryable 属性放在模型中。模型应该是纯粹的简单对象和验证属性。将可查询性保留在您的控制器中。

    【讨论】:

    • 那么如何将数据表中的数据传递到 mvccontrib 网格?据我了解,IQueryable 的迟到允许分页发生在网格中?作为将数据从模型或控制器获取到视图并再次返回的最佳解决方案,您会推荐什么?
    • 保持简单;将您的数据作为 IList 对象发送,将更改存储在简单的 JSON 字符串中以进行持久性或通过 AJAX 更新。以我的经验,MvcContrib 网格比你想要做一些稍微定制的事情的那一刻更痛苦。 (个人意见)
    • 明确一点:随意将集合发送到视图;不要试图将它们从视图中拉回来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多