Adding ELMAH to your ASP.NET Web Site

January 29, 2010 09:59

There's already a lot of posts out there on how to set up ELMAH (see References below). Still, as I went through the process of adding ELMAH to my own site, I found myself pulling information from multiple posts and even ran into a couple of surprises during deployment. So, in an effort to consolidate the information I needed and post solutions to the issues I had, I give you this post on the unhandled exception and error handling utility that is ELMAH.

What is ELMAH?

From the Google Code ELMAH home page:

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

In short, ELMAH is a utility that reports unhandled errors and exceptions. Looked at another way, ELMAH will display problems with your site that you might not otherwise see.

Adding ELMAH to an ASP.NET Web Site

1.) Get ELMAH

The first step is to actually get ELMAH. You can download from the Google Code page. Once you've got it, copy the file "Elmah.dll" into your site's bin folder.

2.) Modifying your web.config

There are a couple of initial modifications you'll have to make to your web.config:

a.) Add the following to the <httpModules> section:

<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>

b.) Add the following to the <httpHandlers> section:

<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

3.) Deployment and dealing with initial issues

For the most basic ELMAH setup, that's it. You should be able to access your site's ELMAH logs by accessing http://yoursite/elmah.axd.

However, once you've deployed you might run into this error:

You are attempting to access ELMAH from a remote machine whereas it is currently configured not to allow remote access.

image

Fortunately, getting around this is pretty easy.

a.) Like it says, add a new <sectionGroup>:

<sectionGroup name="elmah">
    <section name="security" type="Elmah.SecuritySectionHandler, Elmah" />
</sectionGroup>

b.) Also, add the <elmah> section. I added it right underneath my <configSection> closing tag.

<elmah>
    <security allowRemoteAccess="yes" />
</elmah>

Again, redeploy the web.config file and we're done.

Except that, now, everyone in the world can view your ELMAH logs. Not good.

Securing ELMAH against unwanted eyes

Allowing everyone to view your ELMAH logs is generally not a good thing because an astute hacker could easily glean information from those logs and potentially exploit your site. So, we'll add some basic security.

1.) Include the admin path

Include the admin path in the httpHandler "add" so it looks like:

<add verb="POST,GET,HEAD" path="/admin/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

2.) Add a <location> section

This stands as it's own sub-section beneath the main <configuration> tag:

<location path="admin">
    <system.web>
        <authorization>
            <deny users="?"/>
        </authorization>
    </system.web>
</location>

Now, we're done. When you access http://yoursite/admin/elmah.axd, you should be prompted for your credentials (assuming you're using ASP.NET's built-in security; see Phil Haack's post for more info).

If you're using BlogEngine.NET, add ELMAH to your admin menu

This is just an ease-of-access thing. If you add ELMAH to your web.sitemap, BlogEngine.NET will automatically pick it up and display in your admin menu.

Just add this to your sitemap file:

<siteMapNode url="~/admin/elmah.axd" title="ELMAH" description="" roles="administrators"/>

Conclusion

This concludes our discussion on how to add ELMAH to an ASP.NET web site.

References


The IIS SEO Toolkit

December 27, 2009 16:09

Scott Guthrie recently gave a shout-out to the IIS SEO Toolkit on his blog. I don't know about you, but something about SEO always brings up thoughts of greasy salesmen and used cars. Best purge those preconceptions from your mind, though, cause SEO is important.

Even excepting SEO, the SEO Toolkit is a great way to find other issues with a web site. For example, large content files (such as images, which can probably be shrunk down), duplicate keywords, missing meta information, missing content, and other information will all be revealed once you run the Toolkit against your site.

Scott gives a nice overview of the tool; I'll let his discussion get you started and jump right into what the tool showed me.

SEO Toolkit Analysis

Upon running your first analysis you'll get something like this (I ran the analysis against my fiction site, scottmarlowe.com):

image

The statistic I'm most concerned with is the "Number of Violations". I've got over 37,000 of them!

Turns out it's not as bad as it may seem, or not as difficult to whittle that number down anyway. Here is the breakdown of violations:

image

Let's take a look at the big ones (the ones with the highest counts).

1. The page contains unnecessary redirects

Turns out most of these are of this variety:

image

The first link it is indicating is a permalink for a blog post that looks like this:

<a rel="bookmark" href="http://www.scottmarlowe.com/post.aspx? id=f3dc138a-e948-4613-b546-d805fb2703c5">Permalink</a>

This forum post suggests a quick fix for this:

For this particular URL I would consider adding a "nofollow" to the link…

I use BlogEngine.NET; the permalinks were created with "rel=bookmark" already. I couldn't find a whole lot more than this as far as what "bookmark" buys me:

 

Bookmark Refers to a bookmark. A bookmark is a link to a key entry point within an extended document. The title attribute may be used, for example, to label the bookmark. Note that several bookmarks may be defined in each document.

 

But just in case, I also learned that you can specify multiple "rel" tokens just by putting some whitespace between them:

<a rel="bookmark nofollow" href="http://www.scottmarlowe.com/post.aspx? id=f3dc138a-e948-4613-b546-d805fb2703c5">Permalink</a>

That should do it for that violation.

2. The title begins with a brand name

Here are the details:

Search engines often parse text so that words that appear earlier in a sentence are weighted higher than words that appear near the end of a sentence.  Page relevancy is calculated by the use of important keywords that describe the page content. A page about a specific topic should use a keyword related to that topic at the beginning of the <title> tag instead of using a site name or brand name ("scottmarlowe"), because those do not describe the contents on the page.

This one was easy to fix. I'd been using the format "scottmarlowe.com - <page name>" as the title of my document (web page), so based on the recommendation I simply flipped the title so it reads "<page name> – scottmarlowe.com".

3. The page contains multiple canonical formats

A good discussion of this particular violation can be found on the CarlosAg Blog in the post Canonical Formats and Query Strings - IIS SEO Toolkit. The details for one of the violations of this type from my Toolkit analysis reads:

The page with URL "http://www.scottmarlowe.com/category/Book-Reviews.aspx" can also be accessed by using URL "http://www.scottmarlowe.com/category/Book-Reviews.aspx?page=1".
Search engines identify unique pages by using URLs.  When a single page can be accessed by using any one of multiple URLs, a search engine assumes that there are multiple unique pages. Use a single URL to reference a page to prevent dilution of page relevance. You can prevent dilution by following a standard URL format.

I saw two ways of dealing with this violation:

a. Add a Disallow in robots.txt

Add the following to your robots.txt:

Disallow: /*?

This will prevent search bots from using other avenues to access a page they would have already indexed via the main url. This is the approach I took.

b. Add a <link> with rel="canonical"

Add the following for each link:

<link rel="canonical" href="http://www.my-site.com/my-canonical-url" />

Note that this is new and may not be supported by all search engines.

4. The request is disallowed by a Robots.txt rule

This one was informational, and, in fact, was a non-issue as the pages excluded from crawling by my robots.txt were not supposed to be crawled.

5. Large Content Files

The SEO Toolkit does a nice job of displaying your largest files:

image

In my case, I had a few image files that were part of different blog posts that were shrunk when displayed but were, in fact, quite large. A lot of bandwidth was being wasted downloading the oversized images before they were scaled down and rendered on the client machine. Identifying the pages where those images were being used was pretty easy. Just right-click on the image in question and select "View Pages Linking to this Page":

image

I realized I could live without the images on those particular posts so I simply deleted them from the pages where they were being used.

6. Duplicate Description

This turned out to be a programming problem where many pages were having the meta description set twice. I corrected the code and hope to not see the violation again the next time I run the analysis.

Some oddities

The SEO Toolkit does have some known problems. After running my fifth or so analysis I all of a sudden starting seeing the error "Invalid name character… The ':' character, hexadecimal value 0x3A, cannot be included in a name":

image

Turns out this is a known mishandling of meta information by the Toolkit and that there should be a fix released sometime soon. I'll update this post once they do.

Unfortunately this error prevented me from running any more analysis of my site, so I'll have to wait until the fix is released to verify if I've fixed the major violations.

Conclusion

SEO is an often mal-used term, but that doesn't change the fact that it is important if you want to make your site as search engine friendly as possible. The SEO Toolkit is a fast, easy way to help out with this.


Writing a (Completely Useless) Windows 7 Gadget using Silverlight

November 11, 2009 20:12

At its simplest form a Windows gadget is comprised of a .html file and a .xml file. Think of it as a mini-web site, with the .html file representing the site's visual components and the .xml file the gadget config or definition. Of course, as a web site, most gadgets are going to have the usual suspects: css, JavaScript, image files, and—best of all—Silverlight.

The purpose of this post is to allow me to do some research on what Windows gadgets are, how to write them, and, most importantly, how to leverage Silverlight to make gadget development easier and more fun.

What is a Windows Gadget?

When I ask this question, I mean what is a Windows gadget, really? I already know what they are, but what's inside the .gadget file? It's easy to see. Gadget files, which use the .gadget file extension, are just compressed .zip files (much like a .xap in Silverlight). If you change the .gadget extension to .zip, you can then view the files inside just like any other ZIP archive.

Conversely, when you install a .gadget file, its contents are uncompressed to the following location:

C:\Users\<username>\AppData\Local\Microsoft\Windows Sidebar\Gadgets

I'll take a quick look at The Weather Channel gadget (one of the best, IMO):

image

As you can see, it has all the basic components of a standard web site. There are multiple .html files because this gadget, like many others, has a variety of views, each one based on the different gadget states: docked, undocked, fly-out (floating).

The XML Definition File

When you get down to it, the XML definition/config file (not really sure what to call it) is the only thing new. The rest of the gadget is stuff we've seen before.

Here's the generic layout of the .xml definition file, stolen borrowed from Donavon West's Build Your Own Windows Vista Sidebar Gadget article on MSDN:

   1: <?xml version=”1.0encoding=”utf-8” ?>
   2: <gadget>
   3:   <name>Gadget Name Here</name>
   4:   <namespace>YourCompanyNameHere</namespace>
   5:   <version>1.0.0.0</version>
   6:   <author name=”Company Name Here>
   7:     <info url=”http://contoso.comtext=”Visit our Web site/>
   8:     <logo src=”logo.png/>
   9:   </author>
  10:   <copyright>&#0169; 2007</copyright>
  11:   <description>your gadget description</description>
  12:   <icons>
  13:     <icon width=”64height=”64src=”icon.png/>
  14:   </icons>
  15:   <hosts>
  16:     <host name=”sidebar>
  17:       <base type=”HTMLapiVersion=”1.0.0src=”gadget.html/>
  18:       <permissions>full</permissions>
  19:       <platform minPlatformVersion=”0.3/>
  20:     </host>
  21:   </hosts>
  22: </gadget>

Donavon says this about the XML content:

Most of the elements in the definition file are used for displaying the gadget in the gallery. The one truly functional element is the src attribute of the base element—this points to the HTML file that will kickstart the gadget. I make it a practice to name this file gadget.html, but any valid filename will do.

So it's the XML file that acts as a bridge between the gadget hosting app (still sidebar.exe in Windows 7) and the gadget itself.

Creating a Windows Gadget using Silverlight

Creating a gadget that uses Silverlight is surprisingly easy.

1.) Start with a basic Silverlight Application project:

image

I'll call mine SilverlightGadget.

I'll host the control in an ASP.NET Web Site and use Silverlight 3:

image

 

Once the project is created, you can delete the SilverlightGadgetTestPage.aspx from the web site (we aren't going to use it). I also renamed the SilverlightGadgetTestPage.html file to just gadget.html as Donavon recommends.

2.) Next, add a new .xml file to the web site. I called this file gadget.xml to match the naming of the HTML file. Copy the generic <gadget> contents shown above into this new file. You can update information in the file as you see fit. For purposes of this demo, I'll just leave it the way it is except for the gadget's <name> which I'll call SilverlightGadget. The really important line is this file is:

<base type="HTML" apiVersion="1.0.0" src="gadget.html" />

Make sure "src" points to your HTML file.

3.) In gadget.html, we have a couple of changes to make:

a. Make the "html, body" style read "height: 80px; width: 130px;"

   1: html, body {
   2:     height: 80px;
   3:     width: 130px;
   4: }

Make sure to remove the overflow style. It was causing me problems, specifically causing horizontal and vertical scrollbars to display.

The height value was arbitrary; you'll want to adjust based on the content of your gadget. But the width of 130px was a maximum under Vista for a docked gadget. In Windows 7, however, this doesn't seem to apply as I was able to make the gadget as wide as I wanted. Still, all of the other docked gadgets that I have do not exceed this width, so I went with the standard 130px.

b. Add the following param to the list of object <param> tags:

<param name="windowless" value="true" />

This seemed to have the effect of enabling the gadget handles when you mouseover the gadget.

4.) Now, in the XAML, I'll remove the height and width attributes from the UserControl and add a simple button inside the default grid. This gives me:

   1: <UserControl x:Class="SilverlightGadget.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   6:     mc:Ignorable="d">
   7:  
   8:     <Grid x:Name="LayoutRoot" Background="RosyBrown">
   9:         <Button Background="AliceBlue" Width="70" Height="30" Content="Click"  />
  10:     </Grid>
  11: </UserControl>

Yes, I do realize this is a completely useless Silverlight control, but, for now, I'm just trying to demonstrate how to build the gadget by laying some groundwork. Perhaps in a future post I'll share some more useful Silverlight controls to host inside a gadget.

That should be it for the project/code changes. Now, let's install the gadget and see just how useless my one button control is.

Installing the Silverlight Gadget

As mentioned above, a gadget is a just a zip file with the extension .gadget. The easiest way to create a .gadget file is therefore to just use your favorite zip program. Mine is 7za, which I use inside a batch file so that I just double-click or run the batch file from the command line in order to both create and install the gadget.

Here's the sequence of commands (I run this from the project root; the batch file sits alongside the .sln file):

   1: cd SilverlightGadget.Web
   2: del *.gadget
   3: 7za a -r silverlightgadget.zip *
   4: rename *.zip *.gadget
   5: silverlightgadget.gadget
   6: cd ..

I'm just zipping up the whole web site, including the .xap and even the web.config, which isn't needed but this is just demo code so who cares. ;-)

Installing the gadget is as easy as double-clicking the .gadget file or typing the name at the command line and hitting enter. You'll be prompted to install the gadget. Click "Install" and prepared to be impressed:

image

Here it is alongside some other gadgets for better context:

image

Conclusion

While there are a handful of manual steps involved in creating a Silverlight gadget, they're fairly easy ones. It would be great if Visual Studio just had a project template for this, but it doesn't. There are, however, some alternatives out there, including one that does not create a base Silverlight project by Tim Heuer and another by Ioan Lazarciuc which does, but which creates a plethora of projects in the process. In other words, I haven't found a satisfactory Silverlight gadget template yet, so the above steps will have to do for the time being.

Download: SilverlightGadget.zip (solution in VS2010 format)

Resources

[Follow me on Twitter]


Visual Studio 2010 Keyboard & Mouse Shortcuts

October 26, 2009 08:28

Building on my previous VS2008 Shortcuts post, I thought it'd be a good idea to see what Visual Studio 2010 brings to the keyboard and mouse shortcut arena.

While the basis for this list remains those shortcuts outlined in my previous post, I did verify that each of those shortcuts still works. New VS2010 shortcuts are highlighted in blue. Where appropriate, dialogs, etc. have been updated to VS2010. Last, I tried to order entries in a pseudo-alpha format. Barring that, they're logically placed together, so hopefully it makes sense and things are easy to find.

Keyboard Shortcuts

1. Alt-Shift-Enter to View Coding Window Full-screen

alt_key_small-w65 plus shift_key_small_w65 plus enter_key_small_h65   

Hitting "Alt+Shift+Enter" will make the coding window full-screen and (temporarily) drop most other windows from view. Restore to your usual window configuration by de-pressing the "Full Screen" button at top (the fact that it seems to be pushed up a little off-screen must be a VS2010 Beta 2 deal):

image

 

2. Alt-F12 to Find Symbol

alt_key_small-w65plusf12_key_small_h65

Use "Alt-F12" to find symbols, objects, or members.

image

 

3. Ctrl-F to do a Quick Find

ctrl_key_small_h65 plusletter_f_small_h65

Search for something in the current code file quickly with "Ctrl-f". image

 

4. Ctrl-Shift-F to Find in Files

ctrl_key_small_h65plusshift_key_small_h65 plusletter_f_small_h65

Find in files is easy with "Ctrl-Shift-f". image

 

5. Ctrl-K-C to Comment/Uncomment Code

ctrl_key_small_h65plus letter_f_small_h65 plus letter_c_small_h65

You can comment or uncomment code by highlighting the respective code block and hitting "Ctrl-k-c" to comment or "Ctrl-k-u" to uncomment. This shortcut even works in .aspx pages.

image

image

 

6. Ctrl-K-D to Reformat the Entire Document

ctrl_key_small_h65plus letter_k_small_h65 plus letter_d_small_h65

If you want to reformat all of the code in the current document, hit "Ctrl-k-d".

 

7. Ctrl-K-F to Reformat a Block of Code

ctrl_key_small_h65plus letter_k_small_h65plus letter_f_small_h65

If you've just pasted in a bunch of code where the formatting is screwed-up, just highlight it and hit "Ctrl-k-f" to format.

 

8. Ctrl-K-L to Toggle Outlining Ctrl-M-M to Toggle Outlining

ctrl_key_small_h65plus letter_m_small_h65 plus   letter_m_small_h65

If you want to open (expand) or close (collapse) all outlining in a code file, use "Ctrl-k-l". It works like a toggle, alternatively expanding or collapsing all outlining in the current file.

 

9. Ctrl-K-S to Access Code Snippets

ctrl_key_small_h65plusletter_k_small_h65plusletter_s_small_h65   

Easily open the code snippets selection dropdown with "Ctrl-k-s":

image

 

10. Ctrl–K–T to View Call Hierarchy

ctrl_key_small_h65plusletter_k_small_h65plusletter_t_small_h65

Highlight a member operation and hit "Ctrl-k-t" to view it's call hierarchy.

image

A new window will open:

image

 

11. Ctrl-L to Cut Line to Clipboard

ctrl_key_small_h65plus letter_l_small_h65

It's not necessary to highlight an entire line and then hit the delete key. Just hit "Ctrl-L" and the line the cursor is currently on will be removed and copied to the clipboard. "Ctrl-x" performs the same operation by default.

 

12. Ctrl-F3 to Search Without the Dialog

ctrl_key_small_h65plus f3_key_small_h65

ctrl_key_small_h65 plus shift_key_small_h65plus f3_key_small_h65 

Just highlight the text you want to search on and hit "Ctrl-F3" to search down or "Ctrl-Shift-F3" to search up.

 

13. Ctrl-, (Ctrl-Comma) to Perform a Fuzzy 'Navigate To' Search

ctrl_key_small_h65plusimage

Perform a "fuzzy" search and get location information with "Ctrl-," (Ctrl-Comma).

image

 

14. Ctrl-] to Find Matching Curly Brace or Region

ctrl_key_small_h65plus right_curly_brace_paren_small_h65

Position the cursor next to a curly brace ('{' or '}') and hit "Ctrl-}'. This will toggle the cursor between the matching braces.

image

This shortcut will also work for #region...#endregion's.

 

15. F9 to Add/Remove Breakpoint

f9_key_small_h65

'F9' will toggle breakpoints for the current line.

 

16. F12 to Go to Definition

f12_key_small_h65

Put the cursor on an item and hit 'F12'. Instant 'go to definition' functionality.

 

17. Shift-F5 to Stop Debugging

shift_key_small_h65plus f5_key_small_h65

To stop debugging a project, use "Shift-F5". Much quicker than going through the Debug menu.

 

18. Shift-F12 to Find Usages

shift_key_small_h65plusf12_key_small_h65 

'Shift-F12' will find all usages of the item the cursor is currently on and display the "Find Usages" dialog (this is ReSharper's version of the dialog; standard VS2008 looks a little different):

image

 

19. 'prop' to Create New Property

propplustab_key2_small_h65 plustab_key2_small_h65

Add a new property in code by typing prop then hitting the Tab key twice. This "prop-TAB-TAB" combination will create a property template that looks like:

   1: public int MyProperty { get; set; }

 

Mouse Shortcuts

1. Right-click to add references

Say you've just entered a line of code like the following where the red squiggly indicates you haven't yet added the necessary reference (in VS2010 Beta 2, the red squiggly isn't showing up, but the shortcut still works):

image

You could jump to the top of the file and type it in manually, or you could right-click on the squiggly-indicated word and choose "Resolve | using …":

image

This will add the needed reference for you, no typing required.

 

2. Zoom In/Zoom Out

ctrl_key_small_h65plusimage

The same Word functionality of pressing Ctrl and zooming in and out is now in VS2010.

 

3. Remove unused references

Many times there are references included in the "using…" section that are not needed. Removing the unnecessary ones is easy: Right-click anywhere on the code file, select "Organize Usings | Remove Unused Usings".

image

 

4. Sort usings

To sort your "usings…" section, right-click anywhere on the code file and select "Organize Usings | Sort Usings".

image

 

5. Open a file's "containing folder"

Right-click on an open file's tab, select "Open Containing Folder".

image

 

6. Copy a file's folder location to the clipboard

Right-click on an open file's tab, select "Copy Full Path".

image

 

7. Close all files but "this" one

If you have more than one file open, you can right-click on one of the file tabs (the one which you want to stay open) and choose "Close All But This". This will close all other files.

image

 

8. Close tab

A quick way of closing a tab is to use the mouse scroll or middle button. Hover the mouse cursor over the tab, click the mouse scroll button, and the file (and it's tab) will close.


9. Highlight References/Usages

Place the cursor on any member and VS2010 will auto-highlight it throughout:

image

 

Conclusion

Again, if anyone has anything I missed (I know there's got to be a lot), leave a comment. I'd love to learn some new ones!

Sources:

Visual Studio 2010 Keyboard Shortcuts

Visual Studio 2008 Shortcuts

Scott Guthrie: Searching and Navigating Code in VS 2010 (VS 2010 and .NET 4.0 Series)

Visual Studio Editor Blog: Searching and Navigating Code in Visual Studio 2010