我正在攻读MS证书(70-515) 我对网上找到的内容以及练习测试中的内容感到困惑 关于SO的一些问题表明使用RedirectToAction正在向浏览器发送302,从而导致它在地址栏中更改它的url。
但这是一个练习测试的问题:
问题:
MVC Home控制器目前只有默认的Index操作。相关代码显示在以下代码示例中。
public ActionResult Index()
{
ViewData["Message"] = "Hello!";
return View();
}
您需要创建一个名为FindID的动作,该动作显示作为路径一部分输入的ID参数。如果路径不包含ID参数,则ASP.NET必须处理Index操作而不更改浏览器地址栏中的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 Error 302 - Found”响应,这会导致浏览器加载指定的URL。这会更改地址栏中显示的地址。
所以:
- RedirectToAction是否保持浏览器中的URL不变?
- 重定向是否更改了浏览器中的URL?
- 练习测试的解释是否正确?据我所知,RedirectToAction不会执行302.
答案 0 :(得分:10)
您可以使用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-product
发出请求并且some-product
不存在,那么我应该通过相关的状态代码通知用户(对搜索引擎也很重要)。
如果您的FindID操作的唯一目的是使用id参数执行某些操作,那么它不应该是可空/可选的。这样,如果未指定ID,则不会调用FindID操作。
答案 1 :(得分:9)
RedirectToAction方法的文档告诉我们它确实发送了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();
}
这将使用视图Index
,而不是无参数调用FindID
返回的视图View()
。