Asp.net mvc 重定向和重定向操作之间的混淆

Asp.net mvc 重定向和重定向操作之间的混淆,asp.net-mvc,Asp.net Mvc,我正在攻读硕士证书(70-515)。 我对我在网上找到的东西和我在实践测试中读到的东西感到困惑。 关于SO的一些问题表明,使用RedirectToAction会向浏览器发送302,从而导致浏览器更改地址栏中的url 但这是一个来自其中一个实践测试的问题: 问题: MVC主控制器当前只有默认的索引操作。下面的代码示例中显示了相关代码 您需要创建一个名为FindID的操作,该操作显示作为路径的一部分输入的ID参数。如果路径不包含ID参数,ASP.NET必须在不更改浏览器地址栏中URL的情况下处理索引

我正在攻读硕士证书(70-515)。
我对我在网上找到的东西和我在实践测试中读到的东西感到困惑。
关于SO的一些问题表明,使用RedirectToAction会向浏览器发送302,从而导致浏览器更改地址栏中的url

但这是一个来自其中一个实践测试的问题:

问题:

MVC主控制器当前只有默认的索引操作。下面的代码示例中显示了相关代码

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

正确答案:

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

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

Redirect ActionResult向浏览器发送“HTTP错误302-已找到”响应,这将导致浏览器加载指定的URL。这将更改地址栏中显示的地址

所以:
-重定向操作是否使浏览器中的URL保持不变?
-重定向是否会更改浏览器中的URL?
-练习测试的解释正确吗?从这一点上,我理解RedirectToAction并不能实现302

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

这是不正确的

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

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

public ActionResult FindID(int? id)
{
    if (!id.HasValue)
        return View("index");
    ViewData["Message"] = "ID is " + id.ToString();
    return View();
}
然而,我不推荐这种方法。如果我向mysite.com/products/some products发出请求,并且
some product
不存在,那么我应该用相关的状态代码通知用户(对于搜索引擎也很重要)

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

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

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

检查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);
}
测试问题的正确答案是使用不同的观点:

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

这将使用视图
索引
,而不是由无参数调用
view()返回的视图
FindID
,如果重定向到操作!=Server.Transfer,那么你将如何在MVC中进行Server.Transfer?@TweeZz:你不必进行传输,因为你还不在视图中。您只需从控制器返回不同的ActionResult以使用不同的视图。好吧,长话短说:RedirectToAction和RedirectDo302,RedirectToAction只允许您自己不编写完整的URL,而是指定一个操作。在内部,这是完全一样的。对吗?@Ben afaik,return Index();将执行Index方法所做的操作,但随后将尝试FindID视图。这并不完全正确,因为我们希望返回索引视图。我想你必须做的是索引();和返回视图(“索引”)@佩托有很好的斑点。我已经更新了我的答案。只是重申一下,你应该使用重定向方法。我发现整个事情都让优步感到困惑:(好吧,看来认证实践测试中写的东西是错的(可怕!).没有正确答案。我不知道如果我在考试中得到了正确的答案,我该怎么办。我想我会回答现在在考试中被标记为正确的答案。
public ActionResult FindID(int? id) {
  if (!id.HasValue) {
    ViewData["Message"] = "Hello!";
    return View("Index");
  }
  ViewData["Message"] = "ID is " + id.ToString();
  return View();
}