在不同的控制器动作方法之间传递数据
我正在使用ASP.NET MVC 4
。 我正试图从一个控制器传递数据到另一个控制器。 我没有得到这个权利。 我不确定这是否可能?
以下是我想要传递数据的源操作方法:
public class ServerController : Controller { [HttpPost] public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel) { XDocument updatedResultsDocument = myService.UpdateApplicationPools(); // Redirect to ApplicationPool controller and pass // updatedResultsDocument to be used in UpdateConfirmation action method } }
我需要将其传递给此控制器中的此操作方法:
public class ApplicationPoolController : Controller { public ActionResult UpdateConfirmation(XDocument xDocument) { // Will add implementation code return View(); } }
我已经在ApplicationPoolsUpdate
操作方法中尝试了以下内容,但它不起作用:
return RedirectToAction("UpdateConfirmation", "ApplicationPool", new { xDocument = updatedResultsDocument }); return RedirectToAction("UpdateConfirmation", new { controller = "ApplicationPool", xDocument = updatedResultsDocument });
我将如何实现这一目标?
HTTP和redirect
首先回顾ASP.NET MVC的工作原理:
- 当一个HTTP请求进入时,它将与一组路由匹配。 如果路由与请求匹配,则调用与该路由对应的控制器动作。
- 在调用动作方法之前,ASP.NET MVC执行模型绑定。 模型绑定是将HTTP请求的内容(基本上只是文本)映射到操作方法的强types参数的过程
让我们也提醒自己redirect是什么:
HTTPredirect是Web服务器可以发送给客户端的响应,告诉客户端在不同的URL下查找请求的内容。 新的URL包含在Web服务器返回给客户端的Location
标题中。 在ASP.NET MVC中,您通过从操作返回RedirectResult
来执行HTTPredirect。
传递数据
如果您只是传递简单的值(如string和/或整数),则可以将它们作为查询parameter passing给Location
标题中的URL。 这是如果你使用类似的东西会发生什么
return RedirectToAction("ActionName", "Controller", new { arg = updatedResultsDocument });
正如别人所说的那样
这不起作用的原因是XDocument
是一个潜在的非常复杂的对象。 ASP.NET MVC框架没有直接的方式将文档序列化为适合URL的内容,然后将模型从URL值绑定回XDocument
操作参数。
通常,将文档传递给客户端以便客户端在下一个请求中将其传递回服务器是一个非常脆弱的过程:需要各种序列化和反序列化以及各种各样的事情可能出错。 如果文档很大,这可能也是带宽的大量浪费,可能会严重影响应用程序的性能。
相反,你想要做的就是将文档保存在服务器上,并将标识符传回客户端。 客户端随后将标识符与下一个请求一起传递,服务器使用此标识符检索文档。
将数据存储在下一个请求中进行检索
那么,现在的问题就是,服务器在哪里存储文档? 那么,这是你的决定,最好的select将取决于你的特定情况。 如果从长远来看,这个文件需要可用,你可能需要将它存储在磁盘或数据库中。 如果仅包含暂时信息,则将其保存在Web服务器的内存中,在ASP.NETcaching或Session
(或TempData
,与Session
最终相同或多或less)中可能是正确的解决scheme。 无论哪种方式,您将文档存储在一个密钥,以便您稍后检索文档:
int documentId = _myDocumentRepository.Save(updatedResultsDocument);
然后您将该密钥返回给客户端:
return RedirectToAction("UpdateConfirmation", "ApplicationPoolController ", new { id = documentId });
当您想要检索文档时,只需根据键获取它:
public ActionResult UpdateConfirmation(int id) { XDocument doc = _myDocumentRepository.GetById(id); ConfirmationModel model = new ConfirmationModel(doc); return View(model); }
你有没有尝试过使用ASP.NET MVC的TempData ?
ASP.NET MVC TempData字典用于在控制器操作之间共享数据。 TempData的值会一直保持到读取或当前用户的会话超时。 TempData中的数据在redirect等情况下非常有用,当需要超出单个请求的值时。
代码会是这样的:
[HttpPost] public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel) { XDocument updatedResultsDocument = myService.UpdateApplicationPools(); TempData["doc"] = updatedResultsDocument; return RedirectToAction("UpdateConfirmation"); }
在ApplicationPoolController中:
public ActionResult UpdateConfirmation() { if (TempData["doc"] != null) { XDocument updatedResultsDocument = (XDocument) TempData["doc"]; ... return View(); } }
就个人而言,我不喜欢使用TempData,但我更愿意传递一个强types的对象,如ASP.Net-MVC中控制器之间传递信息所述 。
你应该总是find一个明确和预期的方法。
我更喜欢用这个而不是TempData
public class Home1Controller : Controller { [HttpPost] public ActionResult CheckBox(string date) { return RedirectToAction("ActionName", "Home2", new { Date =date }); } }
另一个controller Action
是
public class Home2Controller : Controller { [HttpPost] Public ActionResult ActionName(string Date ) { // do whatever with Date return View(); } }
已经太晚了,但我希望对未来的任何人有所帮助
如果您需要将数据从一个控制器传递到另一个控制器,则必须按路由值传递数据。因为两者都是不同的请求。如果将数据从一个页面发送到另一个页面,则必须使用用户查询string(与路由值相同)。
但是你可以做一个小把戏:
在你的调用动作中,调用被调用的动作是一个简单的方法:
public class ServerController : Controller { [HttpPost] public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel) { XDocument updatedResultsDocument = myService.UpdateApplicationPools(); ApplicationPoolController pool=new ApplicationPoolController(); //make an object of ApplicationPoolController class. return pool.UpdateConfirmation(updatedResultsDocument); // call the ActionMethod you want as a simple method and pass the model as an argument. // Redirect to ApplicationPool controller and pass // updatedResultsDocument to be used in UpdateConfirmation action method } }