在RedirectToAction调用中传递QueryString参数

33
我希望确保查询字符串中的特定参数,我的情况是request_id被传递到重定向的操作。例如,我有一个First动作,
[HttpPost]
public ActionResult First() 
{
    ////////////////////
    // Lots of code ...
    ////////////////////

    return RedirectToAction("Second");
}

假如说第一个postback有一个参数在QueryString里面,我想把它传递给第二个action。其中一种方法是在RedirectToAction函数调用时直接传递这个值。

string requestId = Request.QueryString[REQUEST_ID_KEY];
return RedirectToAction("Second", new { REQUEST_ID_KEY = requestId });

但我必须在一系列的操作中完成这项工作,而且我不想在操作中增加请求 ID 传播逻辑。如果能够将此逻辑纳入到 ActionFilter 中会更好,但我无法找出如何从 ActionFilter 中添加参数到查询字符串。有什么想法吗?

3个回答

53
public class PreserveQueryStringAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var redirectResult = filterContext.Result as RedirectToRouteResult;
        if (redirectResult == null)
        {
            return;
        }

        var query = filterContext.HttpContext.Request.QueryString;
        // Remark: here you could decide if you want to propagate all
        // query string values or a particular one. In my example I am
        // propagating all query string values that are not already part of
        // the route values
        foreach (string key in query.Keys)
        {
            if (!redirectResult.RouteValues.ContainsKey(key))
            {
                redirectResult.RouteValues.Add(key, query[key]);
            }
        }
    }
}

然后:

[HttpPost]
[PreserveQueryString]
public ActionResult First() 
{
    ////////////////////
    // Lots of code ...
    ////////////////////

    return RedirectToAction("Second");
}

1
@Darin.. 仅供了解.. 我能否知道这种实现方式相比于Session或TempData有哪些优势? - alok_dida
2
@alok_dida,TempData在幕后使用Session。个人而言,我从不在我的应用程序中使用Session。我更喜欢以无状态和RESTful的方式进行设计。因此,由于我在web.config中禁用了会话(<sessionState mode="Off" />),所以Session和TempData对我不适用。 - Darin Dimitrov
1
@alok_dida,这已经由Forms身份验证模块为您实现了。当前登录的用户存储在cookie中,您可以使用User.Identity.Name属性在每个操作中检索它。您实际上不需要做任何事情就可以实现这一点。 - Darin Dimitrov
这将在很大程度上取决于属性。您可以扩展身份验证机制并将它们存储在身份验证 cookie 的 userData 部分中。另一个可能性是将它们简单地存储在数据库中,需要时从那里获取。 - Darin Dimitrov
3
在.NET Core中,您将使用Request.Query而不是Request.QueryString。希望能帮助到某些人。 - irriss
显示剩余3条评论

0
如果您需要在后续操作中使用它,请将其添加到Session或TempData参数中(但需要在每个操作中重新分配),这样您就不需要在每个操作中将其作为查询字符串传递。在使用Session时,完成所有操作后,请从Session中删除该键。

我也需要postback中的数据..所以我必须将其传递到QueryString中。 - Arnab Chakraborty
你可以轻松地从Session中获取数据,直到你从会话中删除键为止,这样数据也将在postback操作中可用。 - alok_dida

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接