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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15385442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:36:33  来源:igfitidea点击:

Passing data between different controller action methods

c#asp.netasp.net-mvcasp.net-mvc-3asp.net-mvc-4

提问by Brendan Vogt

I'm using ASP.NET MVC 4. I am trying to pass data from one controller to another controller. I'm not getting this right. I'm not sure if this is possible?

我正在使用ASP.NET MVC 4. 我正在尝试将数据从一个控制器传递到另一个控制器。我不明白这一点。我不确定这是否可能?

Here is my source action method where I want to pass the data from:

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

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

I need to pass it to this action method in this controller:

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

public class ApplicationPoolController : Controller
{
     public ActionResult UpdateConfirmation(XDocument xDocument)
     {
          // Will add implementation code

          return View();
     }
}

I have tried the following in the ApplicationPoolsUpdateaction method but it doesn't work:

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

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

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

How would I achieve this?

我将如何实现这一目标?

采纳答案by Rune

HTTP and redirects

HTTP 和重定向

Let's first recap how ASP.NET MVC works:

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

  1. When an HTTP request comes in, it is matched against a set of routes. If a route matches the request, the controller action corresponding to the route will be invoked.
  2. Before invoking the action method, ASP.NET MVC performs model binding. Model binding is the process of mapping the content of the HTTP request, which is basically just text, to the strongly typed arguments of your action method
  1. 当一个 HTTP 请求进来时,它会与一组路由进行匹配。如果路由与请求匹配,则将调用与该路由对应的控制器操作。
  2. 在调用 action 方法之前,ASP.NET MVC 执行模型绑定。模型绑定是将 HTTP 请求的内容(基本上只是文本)映射到操作方法的强类型参数的过程

Let's also remind ourselves what a redirect is:

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

An HTTP redirect is a response that the webserver can send to the client, telling the client to look for the requested content under a different URL. The new URL is contained in a Locationheader that the webserver returns to the client. In ASP.NET MVC, you do an HTTP redirect by returning a RedirectResultfrom an action.

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

Passing data

传递数据

If you were just passing simple values like strings and/or integers, you could pass them as query parameters in the URL in the Locationheader. This is what would happen if you used something like

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

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

as others have suggested

正如其他人所建议的那样

The reason that this will not work is that the XDocumentis a potentially very complex object. There is no straightforward way for the ASP.NET MVC framework to serialize the document into something that will fit in a URL and then model bind from the URL value back to your XDocumentaction parameter.

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

In general, passing the document to the client in order for the client to pass it back to the server on the next request, is a very brittle procedure: it would require all sorts of serialisation and deserialisation and all sorts of things could go wrong. If the document is large, it might also be a substantial waste of bandwidth and might severely impact the performance of your application.

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

Instead, what you want to do is keep the document around on the server and pass an identifier back to the client. The client then passes the identifier along with the next request and the server retrieves the document using this identifier.

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

Storing data for retrieval on the next request

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

So, the question now becomes, where does the server store the document in the meantime? Well, that is for you to decide and the best choice will depend upon your particular scenario. If this document needs to be available in the long run, you may want to store it on disk or in a database. If it contains only transient information, keeping it in the webserver's memory, in the ASP.NET cache or the Session(or TempData, which is more or less the same as the Sessionin the end) may be the right solution. Either way, you store the document under a key that will allow you to retrieve the document later:

那么,现在的问题就变成了,服务器在此期间将文档存储在哪里?好吧,这由您决定,最佳选择将取决于您的特定情况。如果需要长期使用此文档,您可能希望将其存储在磁盘或数据库中。如果它只包含瞬态信息,将它保存在 web 服务器的内存中,在 ASP.NET 缓存中或Session(或TempDataSession与最终的大致相同)可能是正确的解决方案。无论哪种方式,您都可以将文档存储在一个密钥下,以便您以后检索该文档:

int documentId = _myDocumentRepository.Save(updatedResultsDocument);

and then you return that key to the client:

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

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

When you want to retrieve the document, you simply fetch it based on the key:

当您想要检索文档时,您只需根据键来获取它:

 public ActionResult UpdateConfirmation(int id)
 {
      XDocument doc = _myDocumentRepository.GetById(id);

      ConfirmationModel model = new ConfirmationModel(doc);

      return View(model);
 }

回答by L-Four

Personally I don'tlike to use TempData, but I prefer to pass a strongly typed object as explained in Passing Information Between Controllers in ASP.Net-MVC.

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

You should always find a way to make it explicit and expected.

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

回答by jishnu saha

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

回答by user1073075

Have you tried using ASP.NET MVC TempData?

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

ASP.NET MVC TempData dictionary is used to share data between controller actions. The value of TempData persists until it is read or until the current user's session times out. Persisting data in TempData is useful in scenarios such as redirection, when values are needed beyond a single request.

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

The code would be something like this:

代码将是这样的:

[HttpPost]
public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel)
{
    XDocument updatedResultsDocument = myService.UpdateApplicationPools();
    TempData["doc"] = updatedResultsDocument;
    return RedirectToAction("UpdateConfirmation");
}

And in the ApplicationPoolController:

在 ApplicationPoolController 中:

public ActionResult UpdateConfirmation()
{
    if (TempData["doc"] != null)
    {
        XDocument updatedResultsDocument = (XDocument) TempData["doc"];
            ...
        return View();
    }
}

回答by Amgad Mohamed

I prefer to use this instead of TempData

我更喜欢使用它而不是 TempData

public class Home1Controller : Controller 
{
    [HttpPost]
    public ActionResult CheckBox(string date)
    {
        return RedirectToAction("ActionName", "Home2", new { Date =date });
    }
}

and another controller Actionis

另一个controller Action

public class Home2Controller : Controller 
{
    [HttpPost]
    Public ActionResult ActionName(string Date)
    {
       // do whatever with Date
       return View();
    }
}

it is too late but i hope to be helpful for any one in the future

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