2017-01-20 1 views
0

Контекст:Как показать страницу пользовательской ошибки при удаленном доступе?

Мы хотим использовать страницу ошибки, чтобы показать ошибки пользователя.

В файле Global.asax используется крюк Application_Error для пересылки всех ошибок на страницу пользовательских ошибок в нашем ErrorController. Это ~/Error/Index. Global.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(); 
} 

ErrorController имеет следующий код в Index действий:

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

Вопрос:

Как я могу показать страницу ошибки на удаленном доступ?

+0

прочитайте здесь [здесь] (https://www.asp.net/web-forms/overview/older-versions-getting-started/deploying-web-site-projects/displaying-a-custom-error-page -cs) – crowchirp

+0

@crai: Я думаю, что вы не отвечали на красный вопрос: «Если я добавлю это или нет, поведение будет таким же». Кроме того, страница за вашей ссылкой говорит о YSOD. Как вы видите скриншот в моем вопросе, это не YSOD. – Simon

+0

нормально, получилось, см. Ответы в ответах – crowchirp

ответ

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(); 
    } 
}