asp.net-mvc 重定向和RedirectToAction之间的混淆

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

Confusion between Redirect and RedirectToAction

asp.net-mvc

提问by TweeZz

I'm studying for a MS certificate (70-515).
I'm a confused with what I find online and what I read in a practice test.
A few questions on SO state that using a RedirectToAction is sending the browser a 302, thus causing it to change it's url in the address bar.

我正在学习 MS 证书 (70-515)。
我对我在网上找到的内容和我在练习测试中读到的内容感到困惑。
关于 SO 的几个问题表明,使用 RedirectToAction 会向浏览器发送 302,从而导致它更改地址栏中的 url。

But this is a question from 1 of the practice tests:

但这是来自其中一项练习测试的问题:

QUESTION:

题:

The MVC Home controller currently has only the default Index action. The relevant code is shown in the following code example.

MVC Home 控制器目前只有默认的 Index 操作。相关代码显示在以下代码示例中。

public ActionResult Index()
{
    ViewData["Message"] = "Hello!";
    return View();
}

You need to create an action named FindID that displays the ID parameter entered as part of the path. If the path does not include an ID parameter, ASP.NET must process the Index action without changing the URL in the browser's address bar, and must not throw an exception. Which code segment should you use?

您需要创建一个名为 FindID 的操作,用于显示作为路径一部分输入的 ID 参数。如果路径不包含 ID 参数,ASP.NET 必须在不更改浏览器地址栏中的 URL 的情况下处理 Index 操作,并且不得引发异常。您应该使用哪个代码段?

CORRECT ANSWER:

正确答案:

public ActionResult FindID(int? id)
{
    if (!id.HasValue)
        return RedirectToAction("Index");
    ViewData["Message"] = "ID is " + id.ToString();
    return View();
}

EXPLANATION:

解释:

You can use the RedirectToAction form of ActionResult to cause MVC to process a different action from within an action. MVC abandons the current action and processes the request as if the route had led directly to the action you redirect to. Essentially, this is equivalent to calling Server.Transfer in a standard ASP.NET application.

The Redirect ActionResult sends an "HTTP Error 302 - Found" response to the browser, which causes the browser to load the specified URL. This changes the address that appears in the address bar.

您可以使用 ActionResult 的 RedirectToAction 形式使 MVC 从一个动作中处理不同的动作。MVC 放弃当前操作并处理请求,就像路由直接导致您重定向到的操作一样。本质上,这相当于在标准 ASP.NET 应用程序中调用 Server.Transfer。

Redirect ActionResult 向浏览器发送“HTTP Error 302 - Found”响应,这会导致浏览器加载指定的 URL。这会更改地址栏中显示的地址。

So:
- Does a RedirectToAction leave the URL in browser untouched?
- Does a Redirect change the URL in browser?
- Is the explanation of the practice test correct? From that I understand that RedirectToAction does NOT do a 302.

所以:
- RedirectToAction 是否保留浏览器中的 URL 不变?
- 重定向是否会更改浏览器中的 URL?
-是实践检验的正确的解释?由此我明白 RedirectToAction 不执行 302。

采纳答案by Ben Foster

You can use the RedirectToAction form of ActionResult to cause MVC to process a different action from within an action. MVC abandons the current action and processes the request as if the route had led directly to the action you redirect to. Essentially, this is equivalent to calling Server.Transfer in a standard ASP.NET application.

您可以使用 ActionResult 的 RedirectToAction 形式使 MVC 从一个动作中处理不同的动作。MVC 放弃当前操作并处理请求,就像路由直接导致您重定向到的操作一样。本质上,这相当于在标准 ASP.NET 应用程序中调用 Server.Transfer。

This is incorrect.

这是不正确的。

Both the RedirectToRouteResult (RedirectToAction) and RedirectResult perform a 302 redirect, resulting in the URL in the browser changing.

RedirectToRouteResult (RedirectToAction) 和 RedirectResult 都执行 302 重定向,导致浏览器中的 URL 发生变化。

To return the Index result without changing the url the code would actually be:

要在不更改 url 的情况下返回索引结果,代码实际上是:

public ActionResult FindID(int? id)
{
    if (!id.HasValue)
        return View("index");
    ViewData["Message"] = "ID is " + id.ToString();
    return View();
}

However, I would not recommended this approach. If I make a request to mysite.com/products/some-productand some-productdoes not exist, then I should inform the user of that with the relevant status code (also important for search engines).

但是,我不推荐这种方法。如果我向用户发出请求mysite.com/products/some-product并且some-product不存在,那么我应该用相关的状态代码通知用户(对于搜索引擎也很重要)。

If the sole purpose of your FindID action is to do something with the id parameter, then it should not be nullable/optional. This way the FindID action would not be invoked if an ID was not specified.

如果您的 FindID 操作的唯一目的是对 id 参数执行某些操作,则它不应为可空/可选。这样,如果未指定 ID,则不会调用 FindID 操作。

回答by Guffa

The documentation for the RedirectToActionmethod tells us that it does send a 302 response:

RedirectToAction方法的文档告诉我们它确实发送了 302 响应:

"Returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action."

“向浏览器返回 HTTP 302 响应,这会导致浏览器对指定操作发出 GET 请求。”

Examining the code in the dll reveals that it does return a RedirectToRouteResultobject, which causes a redirect, so the documentation is correct:

检查 dll 中的代码表明它确实返回了一个RedirectToRouteResult对象,这会导致重定向,因此文档是正确的:

protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues) {
  RouteValueDictionary routeValueDictionaries;
  if (this.RouteData == null) {
    routeValueDictionaries = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, null, routeValues, true);
  } else {
    routeValueDictionaries = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, this.RouteData.Values, routeValues, true);
  }
  return new RedirectToRouteResult(routeValueDictionaries);
}

The correct answer to the test question would be to use a different view:

测试问题的正确答案是使用不同的视图:

public ActionResult FindID(int? id) {
  if (!id.HasValue) {
    ViewData["Message"] = "Hello!";
    return View("Index");
  }
  ViewData["Message"] = "ID is " + id.ToString();
  return View();
}

This will use the view Index, instead of the view FindIDthat is returned by the parameterless call View().

这将使用视图Index,而不是FindID由无参数调用返回的视图View()