Friday, June 09, 2006
I do a lot of web development.  Unfortunetely at work all the folks out on the floor have Internet Exploder oops I mean Explorer.  So I do most of my testing in IE6.  The problem comes in as we start to do more DHMTL (AJAX) on our sites.  Ofter you need to view source to see what is rendered.  Well of course IE just gives you little old notepad and calls it good.  Firefox does a better job by at least highlighting syntax.  Well, I've found a good solution for IE.

Notepad++.  Two big bonuses here.  Excellant syntax highlighting and code folding.  Code folding is the ability to expand and contract sections of code so it's out of your way when you don't want to look at it.  The syntax hightlighting is great plus Notepad++ is one great editor in general.  I use it for heavy duty JavaScript development because of the code folding and the lings that line up the beginning and ending tags and code blocks. 

Give it a try.  http://notepad-plus.sourceforge.net/uk/site.htm

I believe it promts you on the install to act as the view source client for IE.


Friday, June 09, 2006 10:53:26 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
If Jerry Seinfeld were a programmer he might ask "What's the deal with configuration files having to be in XML format?".  I just find them to be incredibly hard to read and decipher.  The problem with XML is that it's just so verbose.

Java has property files which may or may not be berrer. Ruby on Rails using YAML files.  These seem fairly reasonable.  One thing an XML file does however is let you show relationships and nesting of data.  So does the complexity of .NET require that the configuration files are also complex?  The configuration file seems to be a collection of serialized objects spat out at random into a file.  Is it a result of the everything must be XML crusades at the turn of the century?  Could the files be simplified?  Could we have seperate config files for seperate concerns.  Example, I go into the config file to change a setting and I typo.  My whole site (or server) goes down.  Is this expected behavior? 

So does the nature of .NET itself demand XML configuration or is this laziness on the programmers part to simply allow them to deserialize the configuration settings in the most convenient way (for them) possible? 

 |  | 
Friday, June 09, 2006 10:43:29 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, June 08, 2006

IF you have a server to monitor that has many different applications, for instance an intranet server, and you want one error logging/reporting solution to rule them all then you've come to the right place.  It took me forever to find this information so I'm going to explain it. 

ASP.NET 2.0 comes with a feature called health monitoring (healthMonitoring).  This feature allows us to configure the monitoring and reporting of information related to ASP.NET.  Almost anything useful can be monitored but I was most concerned about handling server wide exceptions in a consistent manner.  Of course you should handle all errors/exceptions in each application if possible but sometimes this gets overlooked.  In Classic ASP we would route the errors (500's) to a certain page and capture them with the Server.GetLastError which worked just fine in Classic ASP.  However, in ASP.NET this doesn't work so well.  You lose the exception when you transfer to another application.  So you either have to store the exception somewhere by using the application_error or use a solution involving health monitoring.  I chose the latter as a blanket solution just in case anything got through the cracks in an individual application.  I've included a file that will help you set this up. If you want server wide coverage then these settings need to go into the web.config located at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\.  Once you apply these settings you should be able to receive emails and log events to the event log.  You can also set up a SQL provider that will log events to an SQL database instead. 

The important things to look at in the file is the mailSettings tag under the system.net group.  This sets up your SMTP server. 

Next you want to check out the settings in the healthMonitoring section.  This should give you a good idea how to set your server up.  I've noticed that the MSDN examples and documentation is riddled with errors and inconsistencies.  I don't know why they aren't shouting this stuff from the rooftops as it makes application and server administration so much easier.

I've attached the web.config file (web.config.txt (31.22 KB)) to this post.  Here are the relevant sections:

Setting up your SMTP server:

    <system.net>

       <defaultProxy>

            <proxy usesystemdefault="true" />

        </defaultProxy>

      <mailSettings>

        <smtp >

          <network

            defaultCredentials="true"

            host="EMAIL-SERVER-NAME-OR-IP"

           />

        </smtp>

      </mailSettings>

    </system.net>

Health Monitoring (Notice that we add a provider named CriticalMailEventProvider and have the All Errors Default rule use this provider):

<healthMonitoring enabled="true" heartbeatInterval="0">

            <bufferModes>

                <add name="Critical Notification" maxBufferSize="100" maxFlushSize="20"

                    urgentFlushThreshold="1" regularFlushInterval="Infinite" urgentFlushInterval="00:01:00"

                    maxBufferThreads="1" />

                <add name="Notification" maxBufferSize="300" maxFlushSize="20"

                    urgentFlushThreshold="1" regularFlushInterval="Infinite" urgentFlushInterval="00:01:00"

                    maxBufferThreads="1" />

                <add name="Analysis" maxBufferSize="1000" maxFlushSize="100"

                    urgentFlushThreshold="100" regularFlushInterval="00:05:00"

                    urgentFlushInterval="00:01:00" maxBufferThreads="1" />

                <add name="Logging" maxBufferSize="1000" maxFlushSize="200" urgentFlushThreshold="800"

                    regularFlushInterval="00:30:00" urgentFlushInterval="00:05:00"

                    maxBufferThreads="1" />

            </bufferModes>

 

            <providers>

                <add name="EventLogProvider" type="System.Web.Management.EventLogWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />

                <add connectionStringName="LocalSqlServer" maxEventDetailsLength="1073741823"

                    buffer="false" bufferMode="Notification" name="SqlWebEventProvider"

                    type="System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />

                <add name="WmiWebEventProvider" type="System.Web.Management.WmiWebEventProvider,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a" />

             

                <add name="CriticalMailEventProvider"

                  type="System.Web.Management.SimpleMailWebEventProvider"

                  from="CHANGME@PRAGMATICLABS.COM"

                  to="CHANGME@PRAGMATICLABS.COM"

                  bodyHeader="Warning!"

                  bodyFooter="Please investigate ASAP."

                  subjectPrefix="Intranet Error "

                  buffer="true"

                  bufferMode="Critical Notification"

                  maxEventLength="4096"

                  maxMessagesPerNotification="1"

              />

         

            </providers>

 

            <profiles>

                <add name="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00"

                    custom="" />

                <add name="Critical" minInstances="1" maxLimit="Infinite" minInterval="00:00:00"

                    custom="" />

            </profiles>

 

            <rules>

                <add name="All Errors Event Log" eventName="All Errors" provider="EventLogProvider"

                    profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00"

                    custom="" />

                <add name="All Errors Default" eventName="All Errors" provider="CriticalMailEventProvider"

                  profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00"

                  custom="" />

                <add name="Failure Audits Default" eventName="Failure Audits"

                    provider="EventLogProvider" profile="Default" minInstances="1"

                    maxLimit="Infinite" minInterval="00:01:00" custom="" />

               

            </rules>

 

            <eventMappings>

                <add name="All Events" type="System.Web.Management.WebBaseEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Heartbeats" type="System.Web.Management.WebHeartbeatEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Application Lifetime Events" type="System.Web.Management.WebApplicationLifetimeEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Request Processing Events" type="System.Web.Management.WebRequestEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="All Errors" type="System.Web.Management.WebBaseErrorEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Infrastructure Errors" type="System.Web.Management.WebErrorEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Request Processing Errors" type="System.Web.Management.WebRequestErrorEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="All Audits" type="System.Web.Management.WebAuditEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Failure Audits" type="System.Web.Management.WebFailureAuditEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

                <add name="Success Audits" type="System.Web.Management.WebSuccessAuditEvent,System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"

                    startEventCode="0" endEventCode="2147483647" />

            </eventMappings>

 

        </healthMonitoring>

 

Enjoy!

-- EDIT 06/09/2006 Added the web.config as a file attachment to this post and added just the relevant excerpts from the web.config file.


Thursday, June 08, 2006 5:15:36 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, June 07, 2006

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Collections.Specialized;
using System.Web.Caching;

public partial class modules_EditCircuitOrder : System.Web.UI.Page
{
protected