it-swarm.com.de

ASP.NET MVC HandleError

Wie gehe ich beim [HandleError] - Filter in asp.net MVC Preview 5 vor?
Ich habe die customErrors in meiner Web.config-Datei festgelegt

<customErrors mode="On" defaultRedirect="Error.aspx">
  <error statusCode="403" redirect="NoAccess.htm"/>
  <error statusCode="404" redirect="FileNotFound.htm"/>
</customErrors>

und setze [HandleError] wie folgt über meine Controller-Klasse:

[HandleError]
public class DSWebsiteController: Controller
{
    [snip]
    public ActionResult CrashTest()
    {
        throw new Exception("Oh Noes!");
    }
}

Dann lasse ich meine Controller von dieser Klasse erben und rufe CrashTest () auf. Visual Studio hält bei dem Fehler an und nachdem ich f5 gedrückt habe, um fortzufahren, werde ich zu Error.aspx? Aspxerrorpath =/sxi.mvc/CrashTest umgeleitet (wobei sxi der Name des verwendeten Controllers ist. Natürlich kann der Pfad nicht gefunden werden und ich bekomme "Serverfehler in '/' Anwendung." 404.

Diese Seite wurde von Vorschau 3 auf 5 portiert. Alles läuft (war nicht so viel Arbeit zu portieren), außer der Fehlerbehandlung. Wenn ich ein komplett neues Projekt erstelle, scheint die Fehlerbehandlung zu funktionieren.

Ideen?

- Hinweis -
Da diese Frage jetzt mehr als 3 KB-Aufrufe hat, hielt ich es für nützlich, das zu verwenden, was ich derzeit verwende (ASP.NET MVC 1.0). Im mvc contrib project gibt es ein brillantes Attribut namens "RescueAttribute". Sie sollten es sich wahrscheinlich auch ansehen.

109
Boris Callens
[HandleError]

Wenn Sie nur das HandleError-Attribut für Ihre Klasse (oder für Ihre Aktionsmethode) bereitstellen, sucht MVC beim Auftreten einer nicht behandelten Ausnahme zuerst im View-Ordner des Controllers nach einer entsprechenden View mit dem Namen "Error". Wenn es dort nicht zu finden ist, wird im Ordner "Shared View" gesucht (der standardmäßig eine Error.aspx-Datei enthalten sollte).

[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")]
[HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")]

Sie können auch zusätzliche Attribute mit spezifischen Informationen zum Typ der gesuchten Ausnahme stapeln. Zu diesem Zeitpunkt können Sie den Fehler auf eine andere Ansicht als die Standardansicht "Fehler" verweisen.

Weitere Informationen finden Sie in Scott Guthries Blogpost .

156
Elijah Manor

Es sollte auch beachtet werden, dass Fehler, die den http-Fehlercode nicht auf 500 setzen

(z. B. UnauthorizedAccessException)

wird vom HandleError-Filter nicht behandelt.

23
Corin Blaikie

Lösung für http-Fehlercode bis 500. Dies ist ein Attribut namens [ERROR], das einer Aktion zugewiesen wird

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

}

//BEISPIEL:

[Error]
[HandleError]
[PopulateSiteMap(SiteMapName="Mifel1", ViewDataKey="Mifel1")]
public class ApplicationController : Controller
{
}
14
Raul

Attribute in MVC sind sehr nützlich bei der Fehlerbehandlung bei der Methode get und post, sie verfolgen auch Ajax-Aufruf.

Erstellen Sie einen Basiscontroller in Ihrer Anwendung und erben Sie ihn in Ihrem Hauptcontroller (EmployeeController).

öffentliche Klasse EmployeeController: BaseController

Fügen Sie den folgenden Code im Basis-Controller hinzu.

/// <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");
    }

}

==============================================

Findet das Verzeichnis: Root/App_Start/FilterConfig.cs

Fügen Sie folgenden Code hinzu:

/// <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:

Rufen Sie beim Laden der Layout-Seite die CheckAJAXError-Funktion auf.

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

Sie vermissen Error.aspx :) In Vorschau 5 befindet sich dies in Ihrem Ordner Ansichten/Freigegeben. Kopieren Sie es einfach von einem neuen Preview 5-Projekt.

4
Ricky