1

我想将一个大对象从视图传递给控制器​​的操作。像这样:

看法

<div>@Html.ActionLink("Send us an email", "Index", 
"Email", new { o = @Model.Exception }, null)</div>

控制器

public class EmailController : Controller
    {
        [AllowAnonymous]
        public ActionResult Index(object o)
        {
            new BaseServices.Emailer().SendEmail(o);

            return View();
        }

    }

问题是:传递的对象太大了,我猜 MVC 无法从中提出论点并将其添加到路由表/字典中。所以,我的电子邮件控制器的索引操作永远不会被调用。代码在两者之间的某个地方爆炸了。

4

2 回答 2

5

不,你不能这样做。ASP.NET MVC 并不是什么神奇的东西。它依赖于标准的 HTTP 和 HTML。正如您在使用 GET 请求时在 HTTP 中所知道的那样,没有.NET 对象的概念。您不能询问如何在 Web 应用程序中传递对象,因为它没有定义。

有一个查询字符串参数的概念。这就是您可以传递的 => 简单查询字符串参数:

@Html.ActionLink(
    "Send us an email", 
    "Index", 
    "Email", 
    new { id = Model.Exception.Id, text = Model.Exception.Text }, 
    null
)

神奇之处在于 ASP.NET MVC 现在将使用 2 个简单的查询字符串参数(id 和 text)将它们映射到控制器操作中视图模型的相应属性。

但当然,要使其正常工作,ASP.NET MVC 需要知道模型的类型。你不能只使用object,因为这种类型没有也id没有text属性。

所以:

public ActionResult Index(MyViewModel o)

现在但是发送复杂类型呢?好吧,您必须问自己的问题是,为什么首先将这种类型传递给视图?是因为 tfhe 用户应该编辑它的一些属性吗?是这样的话,您应该使用包含允许用户编辑它们的输入字段的 HTML 表单。

但是既然你已经把这个物体固定在一个锚上,那有什么意义呢?服务器可以从最初获取该对象的任何位置获取该对象。因此,您只需将一个简单的 id 传递给服务器:

@Html.ActionLink(
    "Send us an email", 
    "Index", 
    "Email", 
    new { id = Model.Exception.Id }, 
    null
)

并让控制器操作将此 id 作为参数:

public ActionResult Index(int id)

好吧,现在您知道 id => 因此您可以从持久存在该实体的任何位置检索相应的实体。

现在有些人可能会建议您在渲染视图之前将对象存储到会话中,然后从会话中检索该对象。就我个人而言,我不是会话的忠实拥护者,因为它将状态引入应用程序。这意味着如果不先调用第一个操作,您永远不能调用第二个操作。这也意味着您不能将第二个操作添加到浏览器收藏夹中。这也意味着,如果您在网络农场中运行应用程序,则不能再将会话存储在内存中 => 您将不得不为此会话使用进程外存储。会议太麻烦了。

于 2012-12-26T09:36:57.670 回答
1

你不能真正在视图中传递它。

相反,请考虑将异常存储在呈现视图的控制器中的 TempData 中......

public ActionResult DisplayErrorAndOptionToEmailIt()
{

    TempData["LastError"] = m.Exception;
    return View();
}

然后当请求进来时,从临时数据中检索它并通过电子邮件发送它

public ActionResult SendTheEmail()
{
    var e = TempData["LastError"] as Exception;
    if (e != null)
    {
        EmailHelper.SendExceptionEmail(e);
    }
    return View();
}

附带说明一下,存储完整对象不是最佳做法。如果可能,请仅存储您需要的内容:

public ActionResult DisplayErrorAndOptionToEmailIt()
{

    TempData["LastError"] = m.Exception.Message;
    return View();
}
于 2013-10-10T01:14:03.923 回答