繁体   English   中英

在不同的 controller 操作方法之间传递数据

[英]Passing data between different controller action methods

我正在使用ASP.NET MVC 4 我正在尝试将数据从一个 controller 传递到另一个 controller。 我没有做对。 我不确定这是否可能?

这是我要从中传递数据的源操作方法:

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
     }
}

我需要将它传递给此 controller 中的此操作方法:

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 和重定向

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

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

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

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

传递数据

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

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

正如其他人所建议的那样

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

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

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

存储数据以供下次请求检索

那么,现在的问题就变成了,服务器在此期间将文档存储在哪里? 好吧,这由您决定,最佳选择将取决于您的特定情况。 如果需要长期使用此文档,您可能希望将其存储在磁盘或数据库中。 如果它只包含瞬态信息,将它保存在 web 服务器的内存中,在 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);
 }

您是否尝试过使用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();
    }
}

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

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

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

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

如果您需要将数据从一个控制器传递到另一个控制器,您必须通过路由值传递数据。因为两者都是不同的请求。如果您将数据从一个页面发送到另一个页面,那么您必须使用用户查询字符串(与路由值相同)。

但你可以做一招:

在您的调用操作中,将被调用操作作为简单方法调用:

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
 }
}

暂无
暂无

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

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