在不同的控制器操作方法之间传递数据

时间:2013-03-13 12:31:48

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

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

我将如何实现这一目标?

5 个答案:

答案 0 :(得分:64)

HTTP并重定向

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

  1. 当HTTP请求进入时,它与一组路由匹配。如果路由与请求匹配,则将调用与路由对应的控制器操作。
  2. 在调用操作方法之前,ASP.NET MVC执行模型绑定。模型绑定是将HTTP请求的内容(基本上只是文本)映射到操作方法的强类型参数的过程
  3. 让我们自己提醒一下重定向是什么:

    HTTP重定向是网络服务器可以发送给客户端的响应,告诉客户端在不同的URL下查找请求的内容。新URL包含在Web服务器返回给客户端的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,它与{{或多或少相同1}}最后)可能是正确的解决方案。无论哪种方式,您都可以将文档存储在一个密钥下,以便以后检索文档:

    Session

    然后将该密钥返回给客户端:

    int documentId = _myDocumentRepository.Save(updatedResultsDocument);
    

    如果要检索文档,只需根据键获取文档:

    return RedirectToAction("UpdateConfirmation", "ApplicationPoolController ", new { id = documentId });
    

答案 1 :(得分:60)

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

答案 2 :(得分:11)

我个人喜欢使用TempData,但我更喜欢传递一个强类型对象,如Passing Information Between Controllers in ASP.Net-MVC中所述。

你总是应该找到一种方法使它明确和预期。

答案 3 :(得分:2)

我更喜欢使用此代替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();
    }
}

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

答案 4 :(得分:-3)

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

但你可以做一招:

在你的调用动作中,将被调用的动作称为一个简单的方法:

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