上下文
我们希望使用自定义错误页面向用户显示错误。
在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"/>
的否声明。如果我添加或不添加,行为是相同的。
问题:
当我在本地计算机上执行错误时,将按预期显示自定义错误页面。但是当我通过网络上的浏览器从另一台机器调用应用程序时,我得到任何其他错误页面:
问题:
如何在远程访问时显示自定义错误页面?
答案 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();
}
}