asp.net-mvc ASP.NET MVC 句柄错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/183316/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ASP.NET MVC HandleError
提问by Boris Callens
How do I go about the [HandleError]filter in asp.net MVC Preview 5?
I set the customErrors in my Web.config file
我如何处理[HandleError]asp.net MVC Preview 5 中的过滤器?
我在我的 Web.config 文件中设置了 customErrors
<customErrors mode="On" defaultRedirect="Error.aspx">
<error statusCode="403" redirect="NoAccess.htm"/>
<error statusCode="404" redirect="FileNotFound.htm"/>
</customErrors>
and put [HandleError] above my Controller Class like this:
并将 [HandleError] 放在我的控制器类之上,如下所示:
[HandleError]
public class DSWebsiteController: Controller
{
[snip]
public ActionResult CrashTest()
{
throw new Exception("Oh Noes!");
}
}
Then I let my controllers inherit from this class and call CrashTest() on them. Visual studio halts at the error and after pressing f5 to continue, I get rerouted to Error.aspx?aspxerrorpath=/sxi.mvc/CrashTest (where sxi is the name of the used controller. Off course the path cannot be found and I get "Server Error in '/' Application." 404.
然后我让我的控制器从这个类继承并在它们上调用 CrashTest()。Visual Studio 在错误处停止,按 f5 继续后,我被重新路由到 Error.aspx?aspxerrorpath=/sxi.mvc/CrashTest(其中 sxi 是所用控制器的名称。当然找不到路径,我得到“‘/’应用程序中的服务器错误。”404。
This site was ported from preview 3 to 5. Everything runs (wasn't that much work to port) except the error handling. When I create a complete new project the error handling seems to work.
此站点已从预览版 3 移植到预览版 5。除错误处理外,一切都在运行(移植工作量不大)。当我创建一个完整的新项目时,错误处理似乎有效。
Ideas?
想法?
--Note--
Since this question has over 3K views now, I thought it would be beneficial to put in what I'm currently (ASP.NET MVC 1.0) using.
In the mvc contrib projectthere is a brilliant attribute called "RescueAttribute"
You should probably check it out too ;)
--注意--
由于这个问题现在有超过 3K 的视图,我认为放入我目前使用的内容 (ASP.NET MVC 1.0) 会有所帮助。在mvc contrib 项目中有一个很棒的属性叫做“RescueAttribute”你也应该检查一下;)
回答by Elijah Manor
[HandleError]
When you provide only the HandleError attribute to your class (or to your action method for that matter), then when an unhandled exception occurs MVC will look for a corresponding View named "Error" first in the Controller's View folder. If it can't find it there then it will proceed to look in the Shared View folder (which should have an Error.aspx file in it by default)
当您仅向您的类(或您的操作方法)提供 HandleError 属性时,当发生未处理的异常时,MVC 将首先在控制器的视图文件夹中查找名为“错误”的相应视图。如果在那里找不到它,它将继续查看共享视图文件夹(默认情况下应该有一个 Error.aspx 文件)
[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")]
You can also stack up additional attributes with specific information about the type of exception you are looking for. At that point, you can direct the Error to a specific view other than the default "Error" view.
您还可以使用有关您要查找的异常类型的特定信息来堆叠其他属性。此时,您可以将错误定向到默认“错误”视图以外的特定视图。
For more information, take a look at Scott Guthrie's blog postabout it.
有关更多信息,请查看Scott Guthrie 的博客文章。
回答by Corin Blaikie
It should also be noted that errors that don't set the http error code to 500
还需要注意的是,没有将http错误代码设置为500的错误
(e.g. UnauthorizedAccessException)
(例如 UnauthorizedAccessException)
will not be handled by the HandleError filter.
不会被 HandleError 过滤器处理。
回答by Raul
Solution for http error code to 500 this is an attribute called [ERROR] put it on an action
http error code to 500的解决方法这是一个叫做[ERROR]的属性把它放在一个动作上
public class Error: System.Web.Mvc.HandleErrorAttribute
{
public override void OnException(System.Web.Mvc.ExceptionContext filterContext)
{
if (filterContext.HttpContext.IsCustomErrorEnabled)
{
filterContext.ExceptionHandled = true;
}
base.OnException(filterContext);
//OVERRIDE THE 500 ERROR
filterContext.HttpContext.Response.StatusCode = 200;
}
private static void RaiseErrorSignal(Exception e)
{
var context = HttpContext.Current;
// using.Elmah.ErrorSignal.FromContext(context).Raise(e, context);
}
}
//EXAMPLE:
//例子:
[Error]
[HandleError]
[PopulateSiteMap(SiteMapName="Mifel1", ViewDataKey="Mifel1")]
public class ApplicationController : Controller
{
}
回答by Sandip - Full Stack Developer
Attributes in MVC is very useful in error handling at get and postmethod, it also track for ajax call.
MVC 中的属性在get 和 post方法的错误处理中非常有用,它还可以跟踪ajax 调用。
Create a base controller in your application and inherit it in your main controller(EmployeeController).
在您的应用程序中创建一个基本控制器并在您的主控制器(EmployeeController)中继承它。
public class EmployeeController : BaseController
公共类 EmployeeController : BaseController
Add below code in base controller.
在基本控制器中添加以下代码。
/// <summary>
/// Base Controller
/// </summary>
public class BaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
Exception ex = filterContext.Exception;
//Save error log in file
if (ConfigurationManager.AppSettings["SaveErrorLog"].ToString().Trim().ToUpper() == "TRUE")
{
SaveErrorLog(ex, filterContext);
}
// if the request is AJAX return JSON else view.
if (IsAjax(filterContext))
{
//Because its a exception raised after ajax invocation
//Lets return Json
filterContext.Result = new JsonResult()
{
Data = Convert.ToString(filterContext.Exception),
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.Result = new ViewResult()
{
//Error page to load
ViewName = "Error",
ViewData = new ViewDataDictionary()
};
base.OnException(filterContext);
}
}
/// <summary>
/// Determines whether the specified filter context is ajax.
/// </summary>
/// <param name="filterContext">The filter context.</param>
private bool IsAjax(ExceptionContext filterContext)
{
return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
/// <summary>
/// Saves the error log.
/// </summary>
/// <param name="ex">The ex.</param>
/// <param name="filterContext">The filter context.</param>
void SaveErrorLog(Exception ex, ExceptionContext filterContext)
{
string logMessage = ex.ToString();
string logDirectory = Server.MapPath(Url.Content("~/ErrorLog/"));
DateTime currentDateTime = DateTime.Now;
string currentDateTimeString = currentDateTime.ToString();
CheckCreateLogDirectory(logDirectory);
string logLine = BuildLogLine(currentDateTime, logMessage, filterContext);
logDirectory = (logDirectory + "\Log_" + LogFileName(DateTime.Now) + ".txt");
StreamWriter streamWriter = null;
try
{
streamWriter = new StreamWriter(logDirectory, true);
streamWriter.WriteLine(logLine);
}
catch
{
}
finally
{
if (streamWriter != null)
{
streamWriter.Close();
}
}
}
/// <summary>
/// Checks the create log directory.
/// </summary>
/// <param name="logPath">The log path.</param>
bool CheckCreateLogDirectory(string logPath)
{
bool loggingDirectoryExists = false;
DirectoryInfo directoryInfo = new DirectoryInfo(logPath);
if (directoryInfo.Exists)
{
loggingDirectoryExists = true;
}
else
{
try
{
Directory.CreateDirectory(logPath);
loggingDirectoryExists = true;
}
catch
{
}
}
return loggingDirectoryExists;
}
/// <summary>
/// Builds the log line.
/// </summary>
/// <param name="currentDateTime">The current date time.</param>
/// <param name="logMessage">The log message.</param>
/// <param name="filterContext">The filter context.</param>
string BuildLogLine(DateTime currentDateTime, string logMessage, ExceptionContext filterContext)
{
string controllerName = filterContext.RouteData.Values["Controller"].ToString();
string actionName = filterContext.RouteData.Values["Action"].ToString();
RouteValueDictionary paramList = ((System.Web.Routing.Route)(filterContext.RouteData.Route)).Defaults;
if (paramList != null)
{
paramList.Remove("Controller");
paramList.Remove("Action");
}
StringBuilder loglineStringBuilder = new StringBuilder();
loglineStringBuilder.Append("Log Time : ");
loglineStringBuilder.Append(LogFileEntryDateTime(currentDateTime));
loglineStringBuilder.Append(System.Environment.NewLine);
loglineStringBuilder.Append("Username : ");
loglineStringBuilder.Append(Session["LogedInUserName"]);
loglineStringBuilder.Append(System.Environment.NewLine);
loglineStringBuilder.Append("ControllerName : ");
loglineStringBuilder.Append(controllerName);
loglineStringBuilder.Append(System.Environment.NewLine);
loglineStringBuilder.Append("ActionName : ");
loglineStringBuilder.Append(actionName);
loglineStringBuilder.Append(System.Environment.NewLine);
loglineStringBuilder.Append("----------------------------------------------------------------------------------------------------------");
loglineStringBuilder.Append(System.Environment.NewLine);
loglineStringBuilder.Append(logMessage);
loglineStringBuilder.Append(System.Environment.NewLine);
loglineStringBuilder.Append("==========================================================================================================");
return loglineStringBuilder.ToString();
}
/// <summary>
/// Logs the file entry date time.
/// </summary>
/// <param name="currentDateTime">The current date time.</param>
string LogFileEntryDateTime(DateTime currentDateTime)
{
return currentDateTime.ToString("dd-MMM-yyyy HH:mm:ss");
}
/// <summary>
/// Logs the name of the file.
/// </summary>
/// <param name="currentDateTime">The current date time.</param>
string LogFileName(DateTime currentDateTime)
{
return currentDateTime.ToString("dd_MMM_yyyy");
}
}
================================================
================================================
Finds the Directory : Root/App_Start/FilterConfig.cs
查找目录:Root/App_Start/FilterConfig.cs
Add below code:
添加以下代码:
/// <summary>
/// Filter Config
/// </summary>
public class FilterConfig
{
/// <summary>
/// Registers the global filters.
/// </summary>
/// <param name="filters">The filters.</param>
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
Track AJAX Error:
跟踪 AJAX 错误:
Call CheckAJAXError function in layout page load.
在布局页面加载中调用 CheckAJAXError 函数。
function CheckAJAXError() {
$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
var ex;
if (String(thrownError).toUpperCase() == "LOGIN") {
var url = '@Url.Action("Login", "Login")';
window.location = url;
}
else if (String(jqXHR.responseText).toUpperCase().indexOf("THE DELETE STATEMENT CONFLICTED WITH THE REFERENCE CONSTRAINT") >= 0) {
toastr.error('ReferanceExistMessage');
}
else if (String(thrownError).toUpperCase() == "INTERNAL SERVER ERROR") {
ex = ajaxSettings.url;
//var url = '@Url.Action("ErrorLog", "Home")?exurl=' + ex;
var url = '@Url.Action("ErrorLog", "Home")';
window.location = url;
}
});
};
回答by Ricky
You are missing Error.aspx :) In preview 5, this is located in your Views/Shared folder. Just copy it over from a new Preview 5 project.
您缺少 Error.aspx :) 在预览版 5 中,它位于您的 Views/Shared 文件夹中。只需从新的 Preview 5 项目中复制它即可。
回答by Hyman
[HandleError]
public class ErrorController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult NotAuthorized()
{
//401
Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return View();
}
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Forbidden()
{
//403
Response.StatusCode = (int)HttpStatusCode.Forbidden;
return View();
}
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult NotFound()
{
//404
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ViewResult ServerError()
{
//500
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
}
}

