Quote for the Week

"Learn to enjoy every moment of your life"

Tuesday, June 27, 2017

ELMAH Exception Logging Integration in MVC

In this article, Let us see what is ELMAH..

WHAT IS ELMAH?

ELMAH stands for Error Logging Modules And Handlers that provide functionality to logging run time ASP.NET errors.

  •  Enables logging of all unhandled exceptions.
  •  logs all errors in many storages, like - SQL Server, MySQL, Random Access Memory (RAM), SQL Lite, and Oracle.
  • It has functionality to download all errors in CSV file.
  • RSS feed for the last 15 errors
  • Get all error data in JSON or XML format
  • Get all errors to our mailbox
  • Send error log notification to your application
  • Customize the error log by customizing some code.

Implementing into MVC Application

1. Install ELMAH using Nuget package manager into your application.



2.  Configure your web.config with  ELMAH attributes like below:


<?xml version="1.0" encoding="utf-8"?>  
    <!--  
For more information on how to configure your ASP.NET application, please visit  
http://go.microsoft.com/fwlink/?LinkId=301880  
-->  
    <configuration>  
        <configSections>  
            <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->  
            <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />  
            <sectionGroup name="elmah">  
                <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />  
                <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />  
                <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />  
                <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />  
            </sectionGroup>  
        </configSections>  
        <connectionStrings>  
            <add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog=ExceptionLog;Integrated Security=True" providerName="System.Data.SqlClient" />  
        </connectionStrings>  
        <appSettings>  
            <add key="webpages:Version" value="3.0.0.0" />  
            <add key="webpages:Enabled" value="false" />  
            <add key="ClientValidationEnabled" value="true" />  
            <add key="UnobtrusiveJavaScriptEnabled" value="true" />  
            <add key="elmah.mvc.disableHandler" value="false" />  
            <add key="elmah.mvc.disableHandleErrorFilter" value="false" />  
            <add key="elmah.mvc.requiresAuthentication" value="false" />  
            <add key="elmah.mvc.IgnoreDefaultRoute" value="false" />  
            <add key="elmah.mvc.allowedRoles" value="*" />  
            <add key="elmah.mvc.allowedUsers" value="*" />  
            <add key="elmah.mvc.route" value="elmah" />  
            <add key="elmah.mvc.UserAuthCaseSensitive" value="true" />  
        </appSettings>  
        <system.web>  
            <authentication mode="None" />  
            <compilation debug="true" targetFramework="4.5.1" />  
            <httpRuntime targetFramework="4.5.1" />  
  
            <!--add this-->  
            <httpHandlers>  
                <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />  
            </httpHandlers>  
  
            <!--add this-->  
            <httpModules>  
                <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />  
                <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />  
                <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />  
            </httpModules>  
        </system.web>  
        <system.webServer>  
            <!--add this-->  
            <handlers>  
                <add name="Elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />  
            </handlers>  
            <!--add this-->  
            <modules>  
                <remove name="FormsAuthentication" />  
                <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />  
                <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />  
                <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />  
            </modules>  
            <validation validateIntegratedModeConfiguration="false" />  
  
        </system.webServer>  
        <runtime>  
            <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
                <dependentAssembly>  
                    <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />  
                    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
                </dependentAssembly>  
                <dependentAssembly>  
                    <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />  
                    <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />  
                </dependentAssembly>  
            </assemblyBinding>  
        </runtime>  
        <entityFramework>  
            <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">  
                <parameters>  
                    <parameter value="mssqllocaldb" />  
                </parameters>  
            </defaultConnectionFactory>  
            <providers>  
                <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />  
            </providers>  
        </entityFramework>  
        <elmah>  
  
            <!--add this-->  
            <!--. If allowRemoteAccess value is set to 0, then the error log web page can only be viewed locally. If this attribute is set to 1 then the error log web page is enabled for both remote and local visitors.-->  
            <security allowRemoteAccess="0" />  
            <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="DefaultConnection" />  
            <!--add this-->  
        </elmah>  
  
    </configuration>  


3. Now, Let us create a table to log the errors :

CREATE TABLE[dbo].[ELMAH_Error]  
(  
  
    [ErrorId][uniqueidentifier] NOT NULL,  
  
    [Application][nvarchar](60) NOT NULL,  
  
    [Host][nvarchar](50) NOT NULL,  
  
    [Type][nvarchar](100) NOT NULL,  
  
    [Source][nvarchar](60) NOT NULL,  
  
    [Message][nvarchar](500) NOT NULL,  
  
    [User][nvarchar](50) NOT NULL,  
  
    [StatusCode][int] NOT NULL,  
  
    [TimeUtc][datetime] NOT NULL,  
  
    [Sequence][int] IDENTITY(1, 1) NOT NULL,  
  
    [AllXml][ntext] NOT NULL  
  
)  


Create below Stored Procedures :

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

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  

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  
  
)  


That's it, Now your application is ready to track run time errors or exception by your site.

www.<sitename>.com/elmah.axd


Sunday, April 16, 2017

What's New in Visual Studio 2017 ?

In this article, I want to bring up what are the new features added in VS 2017. Microsoft launched VS 2017 on March 07th,  2017 with many fresh and exciting features for Visual Studio developers. On February 24, 2016, Xamarin and Microsoft announced that Microsoft signed a definitive agreement to acquire Xamarin. Microsoft at Build 2016 announced that they will open-source Xamarin SDK and that they will bundle it as a free tool within Visual Studio's integrated development environment.

Now, we are celebrating the 20th anniversary of Visual Studio and one year anniversary and the release of Visual studio 2017 with many features.

There are many updates coming in the new release of Visual Studio. Unfortunately, I won’t be able to cover them all in this Visual Studio 2017 , but I’ll cover a selection of updates. Please take a look at the release notes if you want to know which other updates are in VS 2017.

Here are the ones that stood out for me:

Improved performance


Enhancements to the navigation, IntelliSense, refactoring, code fixes and debugging saves you time and effort on every-day tasks regardless of language or platform:

Visual Studio has been optimized to reduce startup time and solution load time. The very first launch of Visual Studio is at least 50% faster
Visual Studio will now monitor extension performance that impacts startup, solution load, or editing. You will receive alerts about poorly performing extensions via the Notification bar in the IDE
‘Reload all projects’ has been replaced with ‘Reload solution’ to support better performance of switching branches external to Visual Studio.

‘Run to click’ debugging


With the new ‘Run to click’ debugging feature you no longer need to set temporary breakpoints or perform several steps to execute your code and stop on the line you want. While stopped in a break state, you should see the ‘Run to click’ icon appear next to the line of code that your mouse is hovered over. Simply click the icon while debugging and your code should run to that line:

    - Run to click debugging is also a great feature we chose to highlight in this Visual Studio 2017.

Using the ‘Run to click’ feature you can also view information about how fast it took for the block to execute, process memory and CPU usage. Using this you can drill down until you find out exactly where your issues are.

‘Go to All’ feature


You can now navigate through your whole project using the ‘Go to All…’ search that is replacing the ‘Navigate to…’ one. This feature can be found under Edit > Go to > Go to All… or you can use the shortcut ctrl + , or ctrl + t.

I found this search to be extremely powerful especially in bigger applications. After you enter your search query, it will show a dropdown of all the occurrences found. The powerful search looks not only at file names but also within each file and file path. As you move through the dropdown, Visual Studio will open a peek-preview in the temporary dock view to help you find what you’re looking for:

Go to all search is a powerful feature of the new Visual Studio .

‘Find all references’ feature


Updates to the ‘Find all references’ output has now made it much easier to sift your way through the results. The search output now has syntax colouring and splits all the information into their respective columns. These columns can be customized so you only see what you want in the output. Another great addition is that they added ‘Peek preview’ to the output, and hovering your mouse over the reference will show you the block of code that it was found in.


Smarter auto-complete


Adjustments to the IntelliSense autocomplete means no more scrolling through a massive list of possible recommendations. Instead it will jump straight to the most likely option. It can now also tell the difference between capital case and lower case to make using shorthand autocomplete searches even shorter.

The new exception helper


The new version of Visual Studio also includes a new simplified, non-modal, exception helper. This is to help make finding out why exceptions are causing issues in your code easier. You can use this helper to easily view your exception information at glance with instant access to inner exceptions.

If you’re diagnosing a NullReference exception the helper will point out exactly what was null so you can quickly continue investigating the issue.

Using the new exception helper, you can now exclude breaking on exception types thrown from specific modules. To do this, simply click a checkbox to add a condition while stopped at the thrown exception:

'unhandled exception' is one of the benefits of Visual Studio RC 2017.



Almost I covered what I got from release notes.

Any questions, write to : dotnetcircle@gmail.com. Thank you for reading this article.