C# MVC - 使用 RedirectToAction() 传递数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/672143/
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-04 12:45:40  来源:igfitidea点击:

MVC - Passing Data with RedirectToAction()

c#asp.net-mvcredirecttoaction

提问by splatto

I'd like to take data entered in an MVC user form and display it in a different view.

我想获取在 MVC 用户表单中输入的数据并将其显示在不同的视图中。

The class has the following private variable:

该类具有以下私有变量:

IList<string> _pagecontent = new List<string>();

The following action accepts a FormCollection object, validates it, and passes it on to the "Preview" view as a List:

以下操作接受一个 FormCollection 对象,对其进行验证,并将其作为列表传递给“预览”视图:

[Authorize(Roles = "Admins")]
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateContent(FormCollection collection)
{
    if (ModelState.IsValid)
    {
        string PageToInsert = collection["PageToInsert"];
        string PageHeader = collection["PageHeader"];
        string PageBody = collection["PageBody"];

        //validate, excluded...

        _pagecontent.Add(PageToInsert);
        _pagecontent.Add(PageHeader);
        _pagecontent.Add(PageBody);

    }
    return RedirectToAction("Preview", _pagecontent);
}

The Preview view has the following Page Directive for passing a strongly typed object List:

预览视图具有以下用于传递强类型对象列表的页面指令:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Template.Master" Inherits="System.Web.Mvc.ViewPage<List<string>>" %>

I would expect to be able to use the Model object to get my data, but alas I cannot. At the following line, I get an error index out of boundsexception, stating the index must be non-negative and less than the size of the collection:

我希望能够使用 Model 对象来获取我的数据,但可惜我不能。在下一行,我得到一个error index out of bounds异常,说明索引必须是非负的并且小于集合的大小:

<% if (Model[0].ToString() == "0") { %>

And some strange parameters have been added to the URL, as it resolves to http://localhost:1894/Admin/Preview?Capacity=4&Count=3

并且在 URL 中添加了一些奇怪的参数,因为它解析为 http://localhost:1894/Admin/Preview?Capacity=4&Count=3

So I have two questions:

所以我有两个问题:

  1. When I call RedirectToAction and pass it my List, why is it inaccessible in the view's Model object?
  2. What is the proper way to go about doing what I'm trying to do, namely pass a collection of strings to a view for display there?
  1. 当我调用 RedirectToAction 并将其传递给我的 List 时,为什么它在视图的 Model 对象中无法访问?
  2. 做我想做的事情的正确方法是什么,即将字符串集合传递给视图以在那里显示?

采纳答案by MichaelGG

Try using TempData. It is like a single-shot session object. You put values you want into TempData, immediately redirect and get them out. There is a good writeup here: http://blogs.teamb.com/craigstuntz/2009/01/23/37947/

尝试使用 TempData。它就像一个单次会话对象。您将所需的值放入 TempData,立即重定向并取出它们。这里有一篇很好的文章:http: //blogs.teamb.com/craigstuntz/2009/01/23/37947/

回答by Chad Moran

The problem with RedirectToAction is it's returning a HTTP 302 and the browser is then on it's own going and doing a brand new HTTP request. You may want to consider using a cookie and/or session object to persist the data between requests.

RedirectToAction 的问题在于它返回一个 HTTP 302,然后浏览器会自行执行一个全新的 HTTP 请求。您可能需要考虑使用 cookie 和/或会话对象来保存请求之间的数据。

回答by David P

It looks like you are looking for the UpdateModel command:

看起来您正在寻找 UpdateModel 命令:

Check out ScottGu's blog post on the topic:

查看 ScottGu 关于该主题的博客文章:

Improved UpdateModel and TryUpdateModel methods

改进的 UpdateModel 和 TryUpdateModel 方法

回答by yfeldblum

It sounds like you're trying to do:

听起来您正在尝试执行以下操作:

public ActionResult UpdateContent(FormCollection form) {
    ...
    return View("Preview", _pagecontent);
}

Note that a redirection is supposed to be a "clean slate" for the browser (except for things like the auth cookie). You don't get to tell the browser to pass information along to the next request, since the next request should be able to stand on its own. All you get to do is tell the browser what URL to request next. In ASP.NET MVC, when you pass an arguments-object to RedirectToAction, the public properties of that object are appended as query-string parameters to the generated URL.

请注意,重定向应该是浏览器的“干净的石板”(除了 auth cookie 之类的东西)。您不必告诉浏览器将信息传递给下一个请求,因为下一个请求应该能够独立存在。您要做的就是告诉浏览器接下来要请求的 URL。在 ASP.NET MVC 中,当您将参数对象传递给 时RedirectToAction,该对象的公共属性将作为查询字符串参数附加到生成的 URL 中。

回答by AndreasN

The second parameter to RedirectAction is routeValues, not model.

RedirectAction 的第二个参数是 routeValues,而不是模型。

protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);

Try using TempData for the model. Its for persisting data between redirects.

尝试对模型使用 TempData。它用于在重定向之间持久化数据。

回答by andrecarlucci

This is not working because RedirectToAction is actually sending back a Http 302 to the browser. When the browser receives this 302, it does a new request to the server asking for the new page. New request, new temp variables.

这不起作用,因为 RedirectToAction 实际上是将 Http 302 发送回浏览器。当浏览器收到这个 302 时,它会向服务器发出一个新的请求,请求新的页面。新请求,新的临时变量。

You will also face this problem when you try to save/edit/delete something and for some reason you deny it and you have to return the old form again.

当您尝试保存/编辑/删除某些内容并且出于某种原因拒绝它并且您必须再次返回旧表单时,您也会遇到此问题。

So, instead of:

所以,而不是:

return RedirectToAction("Preview", _pagecontent);

Put the Preview logic in a separate method and just call it:

将 Preview 逻辑放在一个单独的方法中并调用它:

return PreviewLogic(_pagecontent);

You can also use the TempData[] dic to persist data for the next request like others have said, but then you will not avoid the 302 additional round trip to the server.

您还可以使用 TempData[] dic 为下一个请求保留数据,就像其他人所说的那样,但是您将无法避免到服务器的 302 额外往返。

回答by Jo?o Miguel

Be careful when using TempData. It works great in a single server environment but in a cloud environment it may not work as expected since you cannot guarantee that the request will hit the same machine. This happens because TempData rely on the asp.net session. But if you are using other session manager like SQL or AppFabric Cache it will work fine.

使用 TempData 时要小心。它在单服务器环境中工作得很好,但在云环境中它可能无法按预期工作,因为您无法保证请求会命中同一台机器。发生这种情况是因为 TempData 依赖于 asp.net 会话。但是,如果您使用其他会话管理器,如 SQL 或 AppFabric Cache,它会正常工作。

回答by TeamEASI.com

Can't you just make 2 action results with the same name and mark 1 of them with HttpPost?

你不能只制作2个同名的动作结果并用HttpPost标记其中的1个吗?

    public ActionResult UpdateContent(FormCollection preview = null)
    {
        return View(preview);
    }
    [HttpPost]
    public ActionResult UpdateContent(FormCollection collection = null, bool preview = false)
    {
        if (preview)
            return UpdateContent(collection);
        else
            return UpdateContent(null);
    }