ChatGPT解决这个技术问题 Extra ChatGPT

MVC - 使用 RedirectToAction() 传递数据

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

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:

[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 bounds exception, stating the index must be non-negative and less than the size of the collection:

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

So I have two questions:

When I call RedirectToAction and pass it my List, why is it inaccessible in the view's Model object? 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?


M
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/


I did try ViewData but couldn't get it working. Same with TempData but I only gave it a brief go before bed last night. The biggest thing is, I really want to avoid these dictionaries and use the strongly typed View Model object
Yea, but your View Model object -- that's not going to stick around strongly typed over an HTTP 302. You can stick the model into TempData and cast it out. (Honestly, I find it easier to half give up on typing when using ASP.NET MVC, since it simply doesn't do it well.)
Link is no longer valid
J
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.


A
AndreasN

The second parameter to RedirectAction is routeValues, not model.

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

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


C
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.


a
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.

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:

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.


y
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.


My reason for not using return View() is because the url will display the calling View (AddContent), not the rendered View (Preview). When the user clicks "submit" button, it calls the same AddContent [Post] action that just rendered the Preview view, so then I cannot hit the Preview [post] action.
Why are you posting to /MyController/AddContent? Why not post to /MyController/Preview?
I trying to have my AddContent action post to Preview, but when I return View("Preview", _pagecontent) it renders Preview but the url says "/Controller/AddContent". Then when I click the button to persist to the database, it again calls the Addcontent post action instead of the Preview post action.
T
TeamEASI.com

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

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

D
David P

It looks like you are looking for the UpdateModel command:

Check out ScottGu's blog post on the topic:

Improved UpdateModel and TryUpdateModel methods


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅