webcam porn

ASP.NET

Extend the GridView

Thursday, February 19th, 2009 | .NET | 1 Comment

The default GridView class has by default a lot of great features. However, some important features are missing. One of the most important is the ability to display the grid even if it is empty.
Here is a great class extending the GridView with some additional features.

http://forums.asp.net/p/1012442/2951765.aspx#2951765

Tags: ,

Web application absolute path

Wednesday, December 17th, 2008 | .NET | No Comments

Just a reminder on how to get the absolute path for the webapplication in ASP.NET

HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) +        VirtualPathUtility.ToAbsolute(HttpContext.Current.Request.ApplicationPath)

This will return http://subdomain.domain.com/applicationname

You can drop those AppSettings with ApplicationPath :)

Tags:

Using log4net in Web Applications – a real-life example

Friday, December 12th, 2008 | .NET | 15 Comments

I have seen many different configurations for Log4Net. Log4Net is a very simple, but flexible framework and there are lot of ways to configure it. Here is a real-life example on how we are using in the applications I am working on.

First off, I won't say that this is the one and only way you should use Log4Net, but it handles most of the scenarios I can think of.  Some people think that one should not write wrappers for the loggers and use the logging framework directly in the class, but to be honest I like the wrapper because it makes it very simple to use the logging framework without too much knowledge on how it works. I would say that 95% of what is being logged, is typically errors and debug/useful information. I can't see any problem using a wrapper as I get the information I need from the loggers.

Goals with this log configuration

  • Most important is of course logging errors. All errors should be logged.
  • Errors should be logged in a global file on the server that will role once a day.
  • Errors should be sent by email.
  • It should be possible to notify important information by email
  • It should be easy for the developers to use the logging framework
  • It should be possible to change log-level without restarting the application

Configuration and setup

Log4Net consists of only one DLL. Get the latest version and put it in your bin folder. Make a reference to it in the Web Application Project.

Log4net.config

Create a new config file in the root of your Web Application. Name it Log4Net.config and paste the following code:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="log4net" 
        type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    </configSections>
    <log4net>
        <appender name="RollingLogFileAppender"
            type="log4net.Appender.RollingFileAppender">
            <threshold value="INFO" />
            <file value="Log\[applicationname].log" />
            <appendToFile value="true" />
            <rollingStyle value="Date" />
            <datePattern value="'.'yyyyMMdd'.log'" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date [%thread] %-5level
                  %logger %X{user} %X{url} - %message%newline" />
            </layout>
        </appender>
        <appender name="SmtpAppenderError" 
                  type="log4net.Appender.SmtpAppender">
            <!--Set threshold for this appender-->
            <threshold value="ERROR" />
            <to value="[someone]@[somewhere.com]" />
            <from value="[someone]@[somewhere.com]" />
            <subject value="Error from [applicationname]" />
            <smtpHost value="[100.100.100.100]" />
            <bufferSize value="1" />
            <lossy value="false" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date %-5level
                %logger %X{user} %X{url} - %message%newline" />
            </layout>
        </appender>
        <appender name="SmtpAppenderNotify"
                  type="log4net.Appender.SmtpAppender">
            <!--Set threshold for this appender-->
            <threshold value="INFO" />
            <to value="[someone]@[somewhere.com]" />
            <from value="[someone]@[somewhere.com]" />
            <subject value="Error from [applicationname]" />
            <smtpHost value="[100.100.100.100]" />
            <bufferSize value="1" />
            <lossy value="false" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date - %message%newline" />
            </layout>
        </appender>
        <root>
            <level value="Error" />        
        </root>
        <logger name="Application">
            <!--Set level for this logger-->
            <level value="INFO" />
            <appender-ref ref="RollingLogFileAppender" />
            <appender-ref ref="SmtpAppenderError" />
        </logger>
        <logger name="Notify">
            <!--Set level for this logger-->
            <level value="INFO" />
            <appender-ref ref="RollingLogFileAppender" />
            <appender-ref ref="SmtpAppenderNotify" />
        </logger>
    </log4net>
</configuration>

Some comments on the Log4net.config file:

  • The RollingFileAppender is great for rolling the logfile once a day.
    • It has a threshold of INFO, meaning it will log anything from the application except debug information
    • The logfiles are created in a subdirectory of web root. This should be changed on the production server to not expose information about the application.
    • The datePattern is specifying how the rolling files are named. The current day will be named "applicationname.log" and yesterdays file will be named "applicationname.log.20081211.log". The rolling file extension (.log)  makes it easy to open the file in the same editor as the current log. All files will be sorted correctly when using the ISO style date in the filename.
    • In the conversionPattern you will see two speacial entries with the following format: %X{name}. These are custom formats which can be used for special purposes. This configuration adds the authenticated username and the url which fails if there is an error. This is useful information.
  • The SmtpAppenders are used for sending emails. It's really not my favourite configuration, spamming the developers or some other people with emails when some errors occur, but some like it.
    • The threshold is different for the two SmtpAppenders, as is the subject of the email.
    • The buffersize is set to 1 in the example, meaning that the email is sent right away when an error occur. Increasing the buffer will hold the email until the buffer is reached. This can be useful on the production server, especially for the Notify appender as it is probably not that important to notify right away.
    • Lossy is set to false, also to send the email right away. It is possible to hold the email until an evaluator is triggered, for instance when a error occurs. Setting lossy to true requires an evaluator.
    • It is possible to add filters to the appenders to determine which emails should be sent and which to drop.
  • There are two specific loggers that the application will use. The root logger can be used to log 3.party libraries also using Log4Net. I like to use specific loggers in the application and enabling the root logger if I am tracing an error where I need more information from 3.party libraries, ie. NHibernate or other frameworks using Log4net. Remember to set the level for the logger. If not set, the default level is WARN, which means INFO messages will not be logged.

To be able to use the Log4Net.config file instead of putting everything into web.config, you will need to add the following line to AssemblyInfo.vb:

<Assembly: log4net.Config.XmlConfigurator(ConfigFile:="Log4Net.config", Watch:=True)>

The advantage of separating the Log4Net configuration is that it is possible to change the configuration of the logging without restarting the application by changing web.config.  It also gives an better overview of the configuration, not having to browse through web.config to find the logging configuration.

Logging unhandled errors

All unhandled errors should be logged, which is pretty easy to achieve in web applications. Here is the Global.asax file:

Imports System.Web
Imports log4net
Imports MainLib
Public Class [Global]
    Inherits System.Web.HttpApplication
    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the application is started
        ' Initialize the logger in this context.
        LogManager.GetLogger(Me.GetType)
        LogHandler.LogInfo("============================", LogHandler.LogType.General)
        LogHandler.LogInfo("    Starting application", LogHandler.LogType.General)
        LogHandler.LogInfo("============================", LogHandler.LogType.General)
    End Sub
    Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the session is started
    End Sub
    Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires at the beginning of each request
    End Sub
    Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires upon attempting to authenticate the use
    End Sub
    Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when an error occurs
        LogHandler.LogError("Unhandled exception occured!",
        HttpContext.Current.User, HttpContext.Current.Request.Url,
        HttpContext.Current.Server.GetLastError())
    End Sub
    Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the session ends
    End Sub
    Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the application ends
    End Sub
End Class

Comments on Global.asax

  • I have added some information logging in the Application_Start event. This will trigger every time the applications starts or recycles. If this occurs often you probably have some problems with resources on the server, ie. too little memory available for the application.
  • Application_Error occurs every time an unhandled error occurs. Use this to log all errors not logged elsewhere.
  • I have to initialize the logging framework in Application_Start by calling

    LogManager.GetLogger(Me.GetType).  I'm not sure whether this is a bug or by design. It is not possible to let the LogHandler do the initialization. LogHandler is a wrapper class located in another assembly, maybe that is a problem, without really knowing why. LogManager is a class in Log4Net.

The LogHandler class

Imports System.Security.Principal
Imports log4net

Public Class LogHandler
    Const _defaultApplicationLogger As String = "Application"

    Public Enum LogType
        General
        Notify
    End Enum

    Public Shared Sub LogError(ByVal message As String, ByVal [error] As Exception)

        Dim logger As ILog = LogManager.GetLogger(_defaultApplicationLogger)
        If Not [error].InnerException Is Nothing Then
            [error] = [error].InnerException
        End If

        If logger.IsErrorEnabled Then
            logger.Error(message, [error])
        End If
    End Sub

    Public Shared Sub LogError(ByVal message As String, _
                                ByVal user As IPrincipal, ByVal url As Uri, _
                                ByVal [error] As Exception)
        SetOptionalParametersOnLogger(user, url)
        LogError(message, [error])
    End Sub

    Public Shared Sub LogInfo(ByVal message As String, ByVal type As LogType)
        Dim logger As ILog = Nothing
        If type = LogType.Notify Then
            logger = LogManager.GetLogger(LogType.Notify.ToString)
        Else
            logger = LogManager.GetLogger(_defaultApplicationLogger)
        End If
        If logger.IsInfoEnabled Then
            logger.Info(message)
        End If
    End Sub

    Public Shared Sub LogWarning(ByVal message As String, ByVal [error] As Exception)
        Dim logger As ILog = LogManager.GetLogger(_defaultApplicationLogger)
        If Not [error].InnerException Is Nothing Then
            [error] = [error].InnerException
        End If
        If logger.IsWarnEnabled Then
            logger.Warn(message, [error])
        End If
    End Sub

    Public Shared Sub LogWarning(ByVal message As String, _
                                 ByVal user As IPrincipal, ByVal url As Uri, _
                                 ByVal [error] As Exception)
        SetOptionalParametersOnLogger(user, url)
        LogWarning(message, [error])
    End Sub

    Private Shared Sub SetOptionalParametersOnLogger(ByVal user As IPrincipal, ByVal url As Uri)
        'set user to log4net context, so we can use %X{user} in the appenders
        If Not user Is Nothing AndAlso user.Identity.IsAuthenticated Then
            MDC.[Set]("user", user.Identity.Name)
        End If

        'set url to log4net context, so we can use %X{url} in the appenders
        MDC.[Set]("url", url.ToString())
    End Sub
End Class

Comments on LogHandler

  • It's a pretty simple class which is easy to use. I could have added more wrapper methods with overload
  • The LogType enum defines whether the message should be notified (emailed) or not.
  • If I forget to set the level on the logger in the Log4Net.config, the logger.IsInfoEnabled will return false.
  • I am using the MDC class in the Log4Net framework to add the custom entries in the logged message for user and url (see Log4Net.config above)

Handling an error and notifying with success

Sometimes when you know what could go wrong and you want to display a nice error message to the user, you could handle the error and display an errormessage to the user.

Example:

Private Function CreateUser() As User
    Dim userName As String = TextBoxUserName.Text
    Dim password As String = TextBoxPassword.Text
    Try
        Dim user As New User(userName, password)
        LogHandler.LogInfo("Yahoo! User with username " & userName & " created.",
                           LogHandler.LogType.Notify)
        Return user
    Catch iunex As InvalidUserNameException
        PageTools.DisplayError(Page, iunex)
        LogHandler.LogWarning("Error creating user with username " & userName, iunex)
    Catch ipex As InvalidPasswordException
        PageTools.DisplayError(Page, ipex)
        LogHandler.LogWarning("Error creating user with password " & password, ipex)
    End Try
    Return Nothing
End Function

Comments on CreateUser:

  • If successful, a notification is sent by email by using the LogInfo method and using LogHandler.Logtype.Notify
  • The User class will throw InvalidUserNameException or InvalidPasswordException in the credentials are invalid. I wish to display the errors to the user instead of displaying a general error page. In real life I would probably use some validation before calling the User constructor, but this is only an example. ;-)
  • In addition to displaying the error to the user, the error is logged as a warning.This means it will be logged, but no email will be sent to the mailbox as this is not an error in the application.
  • All other exceptions raised when creating the user will be caught in Application_Error in Global.asax and logged there.

Loginformation

Ok, now I have all the code I need to do decent logging. So what do I expect to see in the logfiles?

When building the application in DEBUG mode I will see the following in the logfile:

2008-12-11 16:56:24,453 [14] INFO  Application (null) (null) - ============================
2008-12-11 16:56:24,468 [14] INFO  Application (null) (null) -     Starting application
2008-12-11 16:56:24,468 [14] INFO  Application (null) (null) - ============================
2008-12-11 16:56:25,937 [14] WARN Application 3DX5G3J\knuth http://localhost/fdb/default.aspx -
                                  Error creating user with username Knut Hamang
DAL.InvalidUserNameException: Username is already in use! Please select another username.
   at DAL.User..ctor(String username, String password) in C:\Knut\code\Repository\Internal_Systems\fdb\trunk\DAL\User.vb:line 97
   at fdb.default.CreateUser() in C:\Knut\code\Repository\Internal_Systems\fdb\trunk\Web\default.aspx.vb:line 69

Building in RELEASE  mode I get the following information:

2008-12-11 16:59:21,406 [14] INFO  Application (null) (null) - ============================
2008-12-11 16:59:21,421 [14] INFO  Application (null) (null) -     Starting application
2008-12-11 16:59:21,421 [14] INFO  Application (null) (null) - ============================
2008-12-11 16:59:22,812 [14] WARN Application 3DX5G3J\knuth http://localhost/fdb/default.aspx -
                             Error creating user with username Knut Hamang
DAL.InvalidUserNameException: Username is already in use! Please select another username.
   at DAL.User..ctor(String username, String password)
   at fdb.default.CreateUser()

The difference is the stacktrace. I get the stacktrace in both cases, but I also get the line numbers in DEBUG mode. I can still read the trace and locate the method in the file that throws the error. The conclusion is that I get enough information to trace and fix the error, if there is one.

Please leave any comments on the configuration, and feel free to discuss different logging strategies for Web Applications.

Tags: ,

A great article on understanding ViewState

Friday, June 16th, 2006 | .NET | No Comments

This is as important to ASP.NET developers as it is to developers creating server controls (both user controls and custom controls). ViewState is difficult to understand, but when used correctly, it's very powerful.

Read and learn: http://infinitiesloop.blogspot.com/2006/03/truly-understanding-viewstate.html

Tags:

Override the rendering of the ASP.NET 2.0 controls.

Friday, March 31st, 2006 | .NET | No Comments

In April, the ASP.NET team will ship examples on how to use ControlAdapters for the ASP.NET 2.0 controls. This is a really good idea, because very few people knows how to override the rendering of the standard ASP.NET 2.0 controls. The ControlAdapters allows the developers to render the controls in a really nice way instead of using tables, which seems to be the Microsoft way. For instance, the menu control can be rendered with <ul><li> tags and be customized with CSS classes. This is a really nice feature that few people know about.

Check out ScottGu's blog for more information about this.

Tags:

sex free porn xxx porn tube xnxx porn free amateur porn porn tube youporn porn video