76

我正在使用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();
     }
}

我在ApplicationPoolsUpdateaction 方法中尝试了以下方法,但它不起作用:

return RedirectToAction("UpdateConfirmation", "ApplicationPool", new { xDocument = updatedResultsDocument });

return RedirectToAction("UpdateConfirmation", new { controller = "ApplicationPool", xDocument = updatedResultsDocument });

我将如何实现这一目标?

4

5 回答 5

76

HTTP 和重定向

让我们先回顾一下 ASP.NET MVC 的工作原理:

  1. 当一个 HTTP 请求进来时,它会与一组路由匹配。如果路由匹配请求,将调用与该路由对应的控制器操作。
  2. 在调用 action 方法之前,ASP.NET MVC 执行模型绑定。模型绑定是将 HTTP 请求的内容(基本上只是文本)映射到您的操作方法的强类型参数的过程

让我们也提醒自己什么是重定向:

HTTP 重定向是 Web 服务器可以发送给客户端的响应,告诉客户端在不同的 URL 下查找请求的内容。新 URL 包含在LocationWeb 服务器返回给客户端的标头中。RedirectResult在 ASP.NET MVC 中,您通过从操作返回 a 来执行 HTTP 重定向。

传递数据

如果您只是传递字符串和/或整数等简单值,则可以将它们作为查询参数传递到Location标头中的 URL 中。如果您使用类似的东西会发生这种情况

return RedirectToAction("ActionName", "Controller", new { arg = updatedResultsDocument });

正如其他人所建议的那样

这不起作用的原因是它XDocument可能是一个非常复杂的对象。ASP.NET MVC 框架没有直接的方法将文档序列化为适合 URL 的内容,然后将模型从 URL 值绑定回您的XDocument操作参数。

通常,将文档传递给客户端以便客户端在下一次请求时将其传递回服务器,这是一个非常脆弱的过程:它需要各种序列化和反序列化,并且各种事情都可能出错。如果文档很大,也可能会浪费大量带宽,并可能严重影响应用程序的性能。

相反,您要做的是将文档保留在服务器上并将标识符传递回客户端。然后客户端将标识符与下一个请求一起传递,服务器使用此标识符检索文档。

存储数据以在下一个请求时检索

那么,现在的问题就变成了,服务器同时将文档存储在哪里?好吧,这由您决定,最佳选择将取决于您的特定情况。如果该文档需要长期可用,您可能希望将其存储在磁盘或数据库中。如果它只包含临时信息,则将其保存在网络服务器的内存中、ASP.NET 缓存中或Session(或TempData,与最终的或多或少相同Session)可能是正确的解决方案。无论哪种方式,您都将文档存储在允许您稍后检索文档的密钥下:

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);
 }
于 2014-08-08T10:42:15.740 回答
66

您是否尝试过使用ASP.NET MVC TempData

ASP.NET MVC TempData 字典用于在控制器操作之间共享数据。TempData 的值一直持续到它被读取或当前用户的会话超时。在 TempData 中持久化数据在重定向等场景中很有用,当需要值超出单个请求时。

代码将是这样的:

[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();
    }
}
于 2013-03-13T15:08:22.640 回答
11

我个人喜欢使用 TempData,但我更喜欢传递强类型对象,如在 ASP.Net-MVC 中的控制器之间传递信息中所述。

您应该始终找到一种方法使其明确且符合预期。

于 2013-03-13T12:53:32.333 回答
5

我更喜欢使用它而不是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();
    }
}

为时已晚,但我希望将来对任何人有所帮助

于 2016-11-03T14:53:34.593 回答
-3

If you need to pass data from one controller to another you must pass data by route values.Because both are different request.if you send data from one page to another then you have to user query string(same as route values).

But you can do one trick :

In your calling action call the called action as a simple method :

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
 }
}
于 2013-03-13T13:09:15.547 回答