如何在远程访问时显示自定义错误页面?

时间:2017-01-20 13:56:06

标签: c# asp.net-mvc iis asp.net-mvc-5

上下文

我们希望使用自定义错误页面向用户显示错误。

Global.asax文件中,使用Application_Error挂钩将所有错误转发到ErrorController中的自定义错误页面。这是~/Error/IndexGlobal.asax包含以下代码:

protected void Application_Error(Object sender, EventArgs e)
{   
    var lRedirectController = "Error";
    var lRedirectAction = "Index";

    [...]

    var lStatusCode = ?; // will be set dependent on the exception. E.g. 403

    HttpContextWrapper lContextWrapper = new HttpContextWrapper(Context);
    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", lRedirectController);
    routeData.Values.Add("action", lRedirectAction);
    routeData.Values.Add("pStatusCode", lStatusCode);
    routeData.Values.Add("pIsAjaxRequest", lContextWrapper.Request.IsAjaxRequest());

    [...]

    // execute error controller
    using (ErrorController lController = new ErrorController())
    {
        RequestContext requestContext = new RequestContext(lContextWrapper, routeData);
        lController.BaseExecute(requestContext);
    }

    Response.End();
}

ErrorControllerIndex操作中包含以下代码:

public ActionResult Index(bool pIsAjaxRequest = false, string pMessage = null, int pStatusCode = 500, Exception pException = null, string pAdditionalInfo = null)
{
    // assign the status code to the response header
    Response.StatusCode = pStatusCode;

    // [...]

    // if it was an ajax request, return json, else the view
    if (!pIsAjaxRequest)
    {
        // [...]

        return View("Index", "_BlankPage");
    }
    else
    {
        // json response
    }
}

根文件夹中的文件web.config包含<customErrors mode="On"/>声明。如果我添加或不添加,行为是相同的。

问题:

当我在本地计算机上执行错误时,将按预期显示自定义错误页面。但是当我通过网络上的浏览器从另一台机器调用应用程序时,我得到任何其他错误页面:

enter image description here

问题:

如何在远程访问时显示自定义错误页面?

1 个答案:

答案 0 :(得分:0)

您的错误页面

Error.cshtml

从ErrorModel

中输入值
 public class ErrorModel
    {

       public int ErrorCode { get; set; }
       public bool IsHttpException { get; set; }
       public string ViewFile { get; set; }
       public string ErrorUrl { get; set; }
    }

Global.asax中

protected void Application_Error()
        {

            Exception currentEx = Server.GetLastError();
            ErrorModel errorDetail = null; 
            try
            { 
                errorDetail = ConstructError(Context, currentEx);                 
                Context.Items["ErrorObject"] = errorDetail;                 
                Server.ClearError();
                Context.Response.Clear();  
                ReportError();

            }
            finally
            {
                Cleanup(Context, errorDetail);
            }
        }

        private static void Cleanup(System.Web.HttpContext context, ErrorModel errorInfo)
        {

            if (errorInfo != null && !errorInfo.IsAjax && errorInfo.ErrorCode == 500)
            {
                if (context.Session != null)
                {
                    context.Session.Abandon();
                }
            }
        }

        private static ErrorModel ConstructError(System.Web.HttpContext context, Exception currentEx)
        {
            var model = new ErrorModel();            

            model.IsHttpException = currentEx is HttpException;
            model.ErrorCode = model.IsHttpException ? ((HttpException)currentEx).GetHttpCode() : 500;

            model.ViewFile = "~/Views/Error.cshtml";
            model.ErrorUrl = context.Request.Url.PathAndQuery;

            return model;
        }

        private void ReportError()
        {
            Context.Response.ContentType = "text/html";
            var httpWrapper = new HttpContextWrapper(Context);

            var routeData = new RouteData();
            routeData.Values.Add("controller", "error");
            routeData.Values.Add("action", "index");

            var requestCtx = new RequestContext(httpWrapper, routeData);            

                var controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestCtx, "Error");
                controller.Execute(requestCtx);


        }

在ErrorController中

public ActionResult Index()
{
    // Retrieve error object from either HttpContext or Session
    ErrorModel err = this.HttpContext.Items["ErrorObject"] as ErrorModel ?? Session["ErrorObject"] as ErrorModel;           

    this.Response.ClearHeaders();             
        Response.ContentType = "text/html";
        Response.Write(RenderToString(err.ViewFile, err));

}

  private string RenderToString(string controlName, object viewData)
{
    using (var sw = new StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, controlName);
        var viewContext = new ViewContext(ControllerContext, viewResult.View, new ViewDataDictionary(viewData), TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}