• ELMAH在ASP.NET MVC中的使用


    Google:http://code.google.com/p/elmah/
    Demo:
    http://code.google.com/p/elmah/wiki/DotNetSlackersArticle
    Elman:
    http://nuget.org/packages/elmah(Install-Package elmah)
    Compact:
    http://nuget.org/packages/elmah.sqlservercompact(Install-Package elmah.sqlservercompact)

    安装

    最简单的方式通过Nuget获得

    image

    我的环境是MVC4所以安装Elamh.MVC,因为这样会为我们默认配置好大部分的配置,当然也可以安装Elamh(如配置 Adding ELMAH to your ASP.NET Web Site),也可以安装XML,MongDB,MSSQL,MYSQL,Fiter等配置

    Elmah.MVC 依赖与Elmah.corelibrary
    "Could not load type 'Elmah.ErrorLogModule' from assembly 'Elmah'." 这个错误花了好长时间,开始我以为是IIS6与IIS7配置问题,最后发现是项目名与Elmah重复了
    http://stackoverflow.com/questions/8409581/could-not-load-type-elmah-errorlogmodule-from-assembly-elmah

    这里我故意写了句代码

           public ActionResult Index()
            {
                ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。";
                int num = Convert.ToInt32("Irving");
                return View();
            });

    访问:http://localhost:16899/ 显示错误

    当然可以配置不显示错误

     <customErrors defaultRedirect="/Error" mode="RemoteOnly">
          <error redirect="/Error/NotFound" statusCode="404" />
          <error redirect="/Error/Error" statusCode="500" />
     <customErrors/>

    或者将异常抛出去

           public ActionResult Index()
            {
                ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。";
                try
                {
                    int num = Convert.ToInt32("Irving");
                }
                catch (Exception e)
                {
                    ErrorSignal.FromCurrentContext().Raise(e);
                }
                return View();
            }

    访问:http://localhost:16899/elmah

    image

    可以查看详情,以XML 或者JSON方式显示

    储存方式

    Memory

    <elmah>
        <errorLog type="Elmah.MemoryErrorLog, Elmah" size="100" />
    </elmah>

    这个没有什么好说的,正式环境不推荐使用

    XML

    <elmah>
      <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/ElmahXML_Logs" />
    </elmah>

    imageimage

    Email

    <errorMail from="sender@domain.com" 
                 to="receiver@domain.com" 
                 cc="copy@domain.com" 
                 subject="Your Subject"
                 async="true or false"
                 smtpPort="25"
                 smtpServer="smtp.domain.com" 
                 userName="username"
                 password="password" />
    </elmah>

    有关stmp协议看这里 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?b08ene1

    image

    SQLite

    <connectionStrings>
      <add name="ElmahDB" connectionString="data source=~/App_Data/Elmah.db" />
    </connectionStrings>
    <elmah>
      <errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="ElmahDB" />
    </elmah>

    没有测试

    MSSQL

      <elmah>
          <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ElmahConnText" />
      </elmah>
      <connectionStrings>
        <add name="ElmahConnText" connectionString="Data Source=.;Initial Catalog=ElmahDB;User ID=sa;Password=123"/>
      </connectionStrings>

    这里需要手动插件表,脚本如下 或者 Install-Package elmah.sqlservercompact

    image

    View Code
    /*
      
       ELMAH - Error Logging Modules and Handlers for ASP.NET
       Copyright (c) 2004-9 Atif Aziz. All rights reserved.
      
        Author(s):
      
            Atif Aziz, http://www.raboof.com
            Phil Haacked, http://haacked.com
      
       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at
      
          http://www.apache.org/licenses/LICENSE-2.0
      
       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.
      
    */
    
    -- ELMAH DDL script for Microsoft SQL Server 2000 or later.
    
    -- $Id: SQLServer.sql 677 2009-09-29 18:02:39Z azizatif $
    
    DECLARE @DBCompatibilityLevel INT
    DECLARE @DBCompatibilityLevelMajor INT
    DECLARE @DBCompatibilityLevelMinor INT
    
    SELECT 
        @DBCompatibilityLevel = cmptlevel 
    FROM 
        master.dbo.sysdatabases 
    WHERE 
        name = DB_NAME()
    
    IF @DBCompatibilityLevel <> 80
    BEGIN
    
        SELECT @DBCompatibilityLevelMajor = @DBCompatibilityLevel / 10, 
               @DBCompatibilityLevelMinor = @DBCompatibilityLevel % 10
               
        PRINT N'
        ===========================================================================
        WARNING! 
        ---------------------------------------------------------------------------
        
        This script is designed for Microsoft SQL Server 2000 (8.0) but your 
        database is set up for compatibility with version ' 
        + CAST(@DBCompatibilityLevelMajor AS NVARCHAR(80)) 
        + N'.' 
        + CAST(@DBCompatibilityLevelMinor AS NVARCHAR(80)) 
        + N'. Although 
        the script should work with later versions of Microsoft SQL Server, 
        you can ensure compatibility by executing the following statement:
        
        ALTER DATABASE [' 
        + DB_NAME() 
        + N'] 
        SET COMPATIBILITY_LEVEL = 80
    
        If you are hosting ELMAH in the same database as your application 
        database and do not wish to change the compatibility option then you 
        should create a separate database to host ELMAH where you can set the 
        compatibility level more freely.
        
        If you continue with the current setup, please report any compatibility 
        issues you encounter over at:
        
        http://code.google.com/p/elmah/issues/list
    
        ===========================================================================
    '
    END
    GO
    
    /* ------------------------------------------------------------------------ 
            TABLES
       ------------------------------------------------------------------------ */
    
    CREATE TABLE [dbo].[ELMAH_Error]
    (
        [ErrorId]     UNIQUEIDENTIFIER NOT NULL,
        [Application] NVARCHAR(60)  COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [Host]        NVARCHAR(50)  COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [Type]        NVARCHAR(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [Source]      NVARCHAR(60)  COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [Message]     NVARCHAR(500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [User]        NVARCHAR(50)  COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
        [StatusCode]  INT NOT NULL,
        [TimeUtc]     DATETIME NOT NULL,
        [Sequence]    INT IDENTITY (1, 1) NOT NULL,
        [AllXml]      NTEXT COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL 
    ) 
    ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    GO
    
    ALTER TABLE [dbo].[ELMAH_Error] WITH NOCHECK ADD 
        CONSTRAINT [PK_ELMAH_Error] PRIMARY KEY NONCLUSTERED ([ErrorId]) ON [PRIMARY] 
    GO
    
    ALTER TABLE [dbo].[ELMAH_Error] ADD 
        CONSTRAINT [DF_ELMAH_Error_ErrorId] DEFAULT (NEWID()) FOR [ErrorId]
    GO
    
    CREATE NONCLUSTERED INDEX [IX_ELMAH_Error_App_Time_Seq] ON [dbo].[ELMAH_Error] 
    (
        [Application]   ASC,
        [TimeUtc]       DESC,
        [Sequence]      DESC
    ) 
    ON [PRIMARY]
    GO
    
    /* ------------------------------------------------------------------------ 
            STORED PROCEDURES                                                      
       ------------------------------------------------------------------------ */
    
    SET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GO
    
    CREATE PROCEDURE [dbo].[ELMAH_GetErrorXml]
    (
        @Application NVARCHAR(60),
        @ErrorId UNIQUEIDENTIFIER
    )
    AS
    
        SET NOCOUNT ON
    
        SELECT 
            [AllXml]
        FROM 
            [ELMAH_Error]
        WHERE
            [ErrorId] = @ErrorId
        AND
            [Application] = @Application
    
    GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
    
    SET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GO
    
    CREATE PROCEDURE [dbo].[ELMAH_GetErrorsXml]
    (
        @Application NVARCHAR(60),
        @PageIndex INT = 0,
        @PageSize INT = 15,
        @TotalCount INT OUTPUT
    )
    AS 
    
        SET NOCOUNT ON
    
        DECLARE @FirstTimeUTC DATETIME
        DECLARE @FirstSequence INT
        DECLARE @StartRow INT
        DECLARE @StartRowIndex INT
    
        SELECT 
            @TotalCount = COUNT(1) 
        FROM 
            [ELMAH_Error]
        WHERE 
            [Application] = @Application
    
        -- Get the ID of the first error for the requested page
    
        SET @StartRowIndex = @PageIndex * @PageSize + 1
    
        IF @StartRowIndex <= @TotalCount
        BEGIN
    
            SET ROWCOUNT @StartRowIndex
    
            SELECT  
                @FirstTimeUTC = [TimeUtc],
                @FirstSequence = [Sequence]
            FROM 
                [ELMAH_Error]
            WHERE   
                [Application] = @Application
            ORDER BY 
                [TimeUtc] DESC, 
                [Sequence] DESC
    
        END
        ELSE
        BEGIN
    
            SET @PageSize = 0
    
        END
    
        -- Now set the row count to the requested page size and get
        -- all records below it for the pertaining application.
    
        SET ROWCOUNT @PageSize
    
        SELECT 
            errorId     = [ErrorId], 
            application = [Application],
            host        = [Host], 
            type        = [Type],
            source      = [Source],
            message     = [Message],
            [user]      = [User],
            statusCode  = [StatusCode], 
            time        = CONVERT(VARCHAR(50), [TimeUtc], 126) + 'Z'
        FROM 
            [ELMAH_Error] error
        WHERE
            [Application] = @Application
        AND
            [TimeUtc] <= @FirstTimeUTC
        AND 
            [Sequence] <= @FirstSequence
        ORDER BY
            [TimeUtc] DESC, 
            [Sequence] DESC
        FOR
            XML AUTO
    
    GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
    
    SET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GO
    
    CREATE PROCEDURE [dbo].[ELMAH_LogError]
    (
        @ErrorId UNIQUEIDENTIFIER,
        @Application NVARCHAR(60),
        @Host NVARCHAR(30),
        @Type NVARCHAR(100),
        @Source NVARCHAR(60),
        @Message NVARCHAR(500),
        @User NVARCHAR(50),
        @AllXml NTEXT,
        @StatusCode INT,
        @TimeUtc DATETIME
    )
    AS
    
        SET NOCOUNT ON
    
        INSERT
        INTO
            [ELMAH_Error]
            (
                [ErrorId],
                [Application],
                [Host],
                [Type],
                [Source],
                [Message],
                [User],
                [AllXml],
                [StatusCode],
                [TimeUtc]
            )
        VALUES
            (
                @ErrorId,
                @Application,
                @Host,
                @Type,
                @Source,
                @Message,
                @User,
                @AllXml,
                @StatusCode,
                @TimeUtc
            )
    
    GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO

    ErrorFiltering

    我们可以通过代码的方式过滤错误,如我们不想在应用程序发生404错误的时候记录日志,我们只需要在Global.asax文件中自定义

    这里我启用XML与Email两种方式

    <elmah>
        <security allowRemoteAccess="1" />
        <!--XML方式-->
        <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/ElmahXML_Logs"/>
        <!--Email方式-->
        <errorMail from="xxx@163.com" to="xxx@qq.com" subject="ERROR From Elmah:" async="true" smtpPort="25" smtpServer="smtp.163.com" userName="xxx.com" password="xxx>
        <!--内存方式-->
        <!--<errorLog type="Elmah.MemoryErrorLog, Elmah"/>-->
        <!--MSSQL方式-->
        <!--<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ElmahConnText" />-->
      </elmah>

    allowRemoteAccess 中0表示允许本地浏览,1表示允许本地与远程,其他方式没有试(RSS MYSQL ORACEL等)

    protected void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
            {
                FilterError404Exception(e);
                FilterErrorValidationException(e);
                FilterErrorNotFileException(e);
            }
    
            protected void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
            {
                FilterError404Exception(e);
            }
            /// <summary>
            /// 处理404
            /// </summary>
            /// <param name="e"></param>
            void FilterError404Exception(ExceptionFilterEventArgs e)
            {
                if (e.Exception.GetBaseException() is HttpException)
                {
                    HttpException ex = (HttpException)e.Exception.GetBaseException();
    
                    if (ex.GetHttpCode() == 404)
                    {
                        e.Dismiss();
                    }
                }
            }
            /// <summary>
            /// 处理 HttpRequestValidationException
            /// </summary>
            /// <param name="args"></param>
            void FilterErrorValidationException(ExceptionFilterEventArgs args)
            {
                if (args.Exception.GetBaseException() is HttpRequestValidationException)
                {
                    args.Dismiss();
                }
            }
            void FilterErrorNotFileException(ExceptionFilterEventArgs e)
            {
                if (e.Exception.GetBaseException() is FileNotFoundException)
                {
                    e.Dismiss();
                }
            }

    IIS配置

    II6与IIS7+异同,这个貌似跟集成模式与经典模式有关系,MVC中如果是用Nuget安装的话,应该不用考虑这个问题,如果有问题参考下面链接

    安全性

    可以配置<security>节点设置allowRemoteAccess为0,这样就不能够通过远程的方式进行访问,如果想既支持远程查看日志又能够保证安全性,首先设置allowRemoteAccess为1然后需要我们对elmah.axd路径进行权限控制,可以在<loaction>节点下进行相关配置(Form验证)。

    <location path="elmah.axd">
        <system.web>
          <httpHandlers>
            <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
          </httpHandlers>
          <authorization>
            <allow roles="Irving" />
            <deny users="*" />
          </authorization>
        </system.web>
        <system.webServer>
          <handlers>
            <add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
          </handlers>
        </system.webServer>
      </location>

    http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html

    这篇文章非常好,之前有一篇文章讨论 From验证安全性 machineconfig中的key不被篡改的话,能够确保安全性,链接找不到了

    ElmahR

    ElmahR是一个集成了SignalR技术,可以把错误的消息推送到浏览器上,可以在这里看DEMO :http://elmahr.apphb.com/?log=1
    ElmahR = ELMAH + SignalR (1.0.0 released!)
    http://www.codeproject.com/Articles/377394/ElmahR-equals-ELMAH-plus-SignalR-released
    Streaming logs with SignalR 2.0
    http://www.codeproject.com/Articles/758633/Streaming-logs-with-SignalR

    更新:新版本已支持APS.NET MVC 性能路由的调试

    Refer:

    ASP.NET MVC
    http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/logging-error-details-with-elmah-cs
    http://www.codeproject.com/Articles/26468/ELMAH-Error-Loggin-Module-and-Handler-For-unhandle
    http://volaresystems.com/Blog/post/2009/08/23/Handling-Exceptions-in-ASPNET-MVC.aspx
    http://www.hanselman.com/blog/NuGetPackageOfTheWeek7ELMAHErrorLoggingModulesAndHandlersWithSQLServerCompact.aspx
    http://www.codecapers.com/post/Error-Handling-in-MVC-with-ELMAH.aspx
    http://www.cnblogs.com/lerit/archive/2011/03/29/1998396.html

    ASP.NET WEBFROM
    http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/logging-error-details-with-asp-net-health-monitoring-cs
    http://msdn.microsoft.com/en-us/library/aa479332.aspx
    http://www.itscodingtime.com/itscodingtime/post/Adding-ELMAH-to-your-ASPNET-Web-Site.aspx

    ErrorFiltering
    http://code.google.com/p/elmah/wiki/ErrorFiltering

    Securing
    http://code.google.com/p/elmah/wiki/SecuringErrorLogPages
    http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html
    http://www.beletsky.net/2011/03/integrating-elmah-to-aspnet-mvc-in.html
    http://stackoverflow.com/questions/1245364/securing-elmah-in-asp-net-website  (备注)

    IIS
    http://www.asp.net/mvc/tutorials/older-versions/deployment/using-asp-net-mvc-with-different-versions-of-iis-cs
    http://www.cnblogs.com/apsnet/archive/2012/04/28/2474730.html

  • 相关阅读:
    CSS3的box-sizing属性
    html5 --基础笔记2
    html5--基础笔记
    CSS3--阴影,渐变,背景图片
    响应式布局--流式布局
    angular中的this指向问题
    angular中控制器之间的通讯方式
    angular中的$http配置和参数
    console
    h5表单验证的css和js方法
  • 原文地址:https://www.cnblogs.com/Irving/p/2858601.html
Copyright © 2020-2023  润新知