我开发了一个可在我当地的Win 7工作站上正常运行的MVC 4站点。我的工作站安装了MVC 4作为Visual Studio 2010 bolt-on的一部分。
我已将应用程序部署到我的DEV服务器,即Windows Server 2008 R2。请注意,MVC 4未安装到DEV服务器上,而是应用程序使用MVC bin可部署程序。在某些情况下我会调用error controller
,但我不确定为什么。这是例外:
System.InvalidOperationException:视图'错误'或其主人是 找不到或没有视图引擎支持搜索的位置。该 搜索了以下位置: 〜/查看/客户/ Error.cshtml 〜/查看/客户/ Error.vbhtml 〜/查看/共享/ Error.cshtml 〜/查看/共享/ Error.vbhtml
堆栈跟踪不显示有关异常发生位置的任何行号。除了它之外,MVC似乎希望首先找到与Customer控制器关联的视图,然后检查共享。但是,在任何一条路径中都没有视图,并且不应该存在。
该网站在Application_Error
中使用global.asax.cs
使用全局错误处理程序:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError().GetBaseException();
ILogger httplog = new HttpLogIt(new HttpContextWrapper(Context));
if (new HttpRequestWrapper(Request).IsAjaxRequest())
{
httplog.Error(1, Enums.ErrorCode.INTERNAL_SERVER_ERROR, "An application error occurred during an AJAX request. See exception for details.", ex, false);
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Response.ContentType = "application/json";
Response.Write(new JavaScriptSerializer().Serialize(new
{
errorMessage = "We apologize, the website has experienced an error. Please try again."
}));
return;
}
else
{
httplog.Error(1, Enums.ErrorCode.INTERNAL_SERVER_ERROR, "An application error occurred. See exception for details.", ex, false);
}
Response.Clear();
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// try to send error info to Error controller
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
// maintain current url, even if invalid, when displaying error page
routeData.Values.Add("url", Context.Request.Url.OriginalString);
if (ex is HttpException)
{
HttpException httpException = ex as HttpException;
switch (httpException.GetHttpCode())
{
case 404:
// Page not found.
routeData.Values.Add("action", "Http404");
break;
default:
routeData.Values.Add("action", "Unavailable");
break;
}
}
else
{
routeData.Values.Add("action", "Unavailable");
}
// Pass exception details to the target error View.
var model = new HandleErrorInfo(ex, routeData.Values["controller"].ToString(), routeData.Values["action"].ToString());
routeData.Values.Add("errorinfo", model);
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
从全局处理程序到Error控制器的重新路由落在Error控制器中,它在那里显式设置要使用的视图:
[SessionState(SessionStateBehavior.Disabled)]
public class ErrorController : Controller
{
private ILogger _httplog;
public ErrorController()
{
_httplog = new HttpLogIt(this.HttpContext, this.RouteData);
}
public ActionResult Http404()
{
if (this.ControllerContext.RouteData.Values["errorinfo"] != null)
{
HandleErrorInfo errorinfo = null;
errorinfo = (HandleErrorInfo)this.ControllerContext.RouteData.Values["errorinfo"];
_httplog.Warn(1, Enums.WarningCode.PAGE_NOT_FOUND, "A global application exception was handled and the end user was redirected to the Error Controller with Http404 Action.");
}
Response.StatusCode = (int)HttpStatusCode.NotFound;
// explicitly set the View below
return View("Error404");
}
public ActionResult Http500()
{
if (this.ControllerContext.RouteData.Values["errorinfo"] != null)
{
HandleErrorInfo errorinfo = null;
errorinfo = (HandleErrorInfo)this.ControllerContext.RouteData.Values["errorinfo"];
_httplog.Error(1, Enums.ErrorCode.INTERNAL_SERVER_ERROR, "A global application exception was handled and the end user was redirected to the Error Controller with Http500 Action.", errorinfo.Exception, true);
}
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// explicitly set the View below
return View("Unavailable");
}
public ActionResult Unavailable()
{
if (this.ControllerContext.RouteData.Values["errorinfo"] != null)
{
HandleErrorInfo errorinfo = null;
errorinfo = (HandleErrorInfo)this.ControllerContext.RouteData.Values["errorinfo"];
_httplog.Error(1, Enums.ErrorCode.INTERNAL_SERVER_ERROR, "A global application exception was handled and the end user was redirected to the Error Controller with Unavailable Action.", errorinfo.Exception, true);
}
Response.StatusCode = (int)HttpStatusCode.OK;
// explicitly set the View below
return View("Unavailable");
}
}
我在每种方法中添加了add'l登录以试图找到罪魁祸首,但无济于事。奇怪的是,通过添加额外的日志记录,当抛出并记录此异常时,全局错误处理程序不会触发!
有没有人遇到这样的事情?
答案 0 :(得分:0)
尝试在web.config中添加此行
<customErrors mode="On" />
答案 1 :(得分:0)
添加了更多日志记录并找到了罪魁祸首。在Error
控制器Http404
操作中,我添加了以下日志记录块
_httplog.Info(String.Format("Controller is {0}, Action is {1} and URL is {2}.",
RouteData.Values["controller"].ToString(),
RouteData.Values["action"].ToString(),
RouteData.Values["url"].ToString()));
结果日志显示:
消息:控制器是错误,操作是Http404,URL是__utm.gif。
这是一个Google Analytics图片文件,我在性能监控期间在服务器转储中看到了gif
调用,但是,它与我的Error
控制器触发没有关联。由于我的网站是子网站,而父网站使用GA
,因此在DEV环境中启用了urchin
脚本。
这就是它被解雇的原因 - 在RouteConfig.cs
中,最后一个条目处理所有错误的URL并将它们路由到Error
控制器,Http404
操作,如下所示:
routes.MapRoute("BadRoute", "{*url}", new { controller = "Error", action = "Http404" });
这是为了处理任何错误的网址路径并保留当前网址,而不是显示IIS 404
或customerror
html网页。
这回答了为什么我的Error
控制器在代码之外被调用的问题,但是没有回答为什么MVC框架寻找具有匹配的默认视图的不同错误控制器的原因。修复此问题需要禁用FilterConfig.cs
filters.Add(new HandleErrorAttribute());
尽管global.asax中的应用程序处理错误,但仍在解雇。希望这有帮助!