尽管明确设置它,MVC 4仍会查找默认视图

时间:2013-12-23 14:17:18

标签: c# asp.net-mvc-4

我开发了一个可在我当地的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登录以试图找到罪魁祸首,但无济于事。奇怪的是,通过添加额外的日志记录,当抛出并记录此异常时,全局错误处理程序不会触发!

有没有人遇到这样的事情?

2 个答案:

答案 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 404customerror html网页。

这回答了为什么我的Error控制器在代码之外被调用的问题,但是没有回答为什么MVC框架寻找具有匹配的默认视图的不同错误控制器的原因。修复此问题需要禁用FilterConfig.cs

中的以下行
  

filters.Add(new HandleErrorAttribute());

尽管global.asax中的应用程序处理错误,但仍在解雇。希望这有帮助!