我正在构建我的第一个ASP.NET MVC网站,我正在试图弄清楚如何实现404页面.
我应该创建一个名为"404Controller?"的控制器吗?如果是这样,我如何在IIS中注册此控制器,以便将404重定向到该页面?此外,在某些其他控制器代码未找到某些内容(例如,在数据库中)的情况下,如何将请求重定向到我的404页面?
我在global.asax的底部有以下路由:
//404 ERRORS:
routes.MapRoute(
"404-PageNotFound",
"{*url}",
new { controller = "Error", action = "PageNotFound" }
);
Run Code Online (Sandbox Code Playgroud)
哪个在Visual Studio中工作正常,但在生产中我得到了IIS错误页面.
这条路线不应该捕获任何未被其他人捕获的URL,因此从IIS的角度来看没有404吗?我还需要在web.config中做些什么吗?
注:我不希望重定向到一个404特定URL; 而是我在请求的URL上提供404错误页面(我认为从可用性的角度来看这是正确的方法).
更新
在我的错误控制器中,我正在设置Response.StatusCode = 404;,这似乎是问题.当我删除它并再次部署到生产时,我再次获得友好的错误页面.但是,我相信我确实需要HTTP标头中的404状态 - 出于搜索引擎优化的目的 - 所以现在我的问题变为:
修订问题
IIS如何/为什么拦截响应并发送其开箱即用的404错误,我该如何防止这种情况?
**解决方案**
Dommer获得奖品以表明Response.TrySkipIisCustomErrors=true;哪些(我认为)是必要的.但还有另外两个关键细节:
让它在任何地方工作
由于某些URL可能会映射到"404-PageNotFound"以外的路由但包含无效参数,并且由于我不想重定向到404页面,因此我在基本控制器中创建了此操作:
[HandleError]
public ActionResult NotFound()
{
Response.StatusCode = 404;
Response.TrySkipIisCustomErrors = true;
return View("PageNotFound", SearchUtilities.GetPageNotFoundModel(HttpContext.Request.RawUrl));
}
Run Code Online (Sandbox Code Playgroud)
并且在任何继承基础的控制器动作中,每当我捕获无效的路由参数时,我只需要调用它:
return NotFound();
Run Code Online (Sandbox Code Playgroud)
注意:不是 RedirectToAction()
锦上添花:
我生成并传递到视图中的模型是将URL的多余部分输入到我们的搜索引擎中,并在友好的404页面上显示前3个结果作为建议.
我的小ASP.NET MVC应用程序收到了很多关于伪装"setup.php"页面的请求(每周容易200多个).我猜这是一些试图在网络上发现易受攻击的网站的机器人.这不是一个大问题,但它确实倾向于用垃圾填满我的错误日志,并且可能更难找到需要修复的实际问题.
我想要做的是创建一个路径来处理所有.php请求(以及可能的其他明显虚假的扩展)并以某种方式处理它们.什么是太棒了将立即中止请求,以便我的应用程序不会浪费时间/带宽创建和发送响应(即使它只是一个404).此外,假设这些是恶意请求,那么让他们的服务器坐下来等待超时而不是立即响应并快速继续尝试别人的服务器会很棒:)
所以,我想这是一个2部分的问题.
是否可以在不发送响应的情况下直接停止在ASP.NET/MVC中处理请求
这个问题有更好的解决方案吗?
我只需要一个类似CMS的小型控制器.最简单的方法是这样的:
public class HomeController : Controller {
public ActionResult View(string name) {
if (!ViewExists(name))
return new HttpNotFoundResult();
return View(name);
}
private bool ViewExists(string name) {
// How to check if the view exists without checking the file itself?
}
}
Run Code Online (Sandbox Code Playgroud)
问题是如果没有可用的视图,如何返回HTTP 404?
可能我可以在适当的位置检查文件并缓存结果,但这感觉非常脏.
谢谢,
德米特里.
在Details,Edit,Delete操作方法,我们有id参数,从数据库中检索相应的记录.
如果没有记录对应id,我们有两个选择:
执行操作方法返回一个特定视图,通常命名为 目录
NoFound.cshtml下Views\Shared,以通知用户该 视图id无效.
要么
执行操作方法将用户重定向到特定的操作方法,例如
public ActionResult NoFound (string message),以通知用户该问题.
我的问题是:当没有与给定id关联的记录时,action方法应该执行哪些操作?返回NoFound视图还是重定向到NoFound动作方法?
编辑1 我需要从技术角度出发的理由,例如安全性和性能.