Solution to not being able to use copyright symbol in an Umbraco Macro

Was writing some XSLT for an Umbraco site recently, needed a copyright block in the footer so thought i’d just use the standard

©

syntax to add the copyright symbol, ©. When I tried to save the file, I got an error that the xml was invalid.

Turns out that © is not allowed so I used the numeric value instead

©

which works a treat.

I wonder how many times this has caught people out!

Stopping client side validation and postbacks

A couple of ways to stop client side validation firing, especially when using non asp.net controls:

Set the onclick event of the image/button etc to be onclick=”return false;” then instead of using the onclick event to fire a method, use the onmouseup event instead i.e. onmouseup =”javascript:do originalmethod(this);”

This will stop the page posting back but will fire the javascript method for the control in question. This comes in useful if you have a contact form with validation and a separate control i.e. for directions where you can enter a postcode and use javascript to fire off google maps in another page.

Redirect your user to their starting point when validation errors occur

Ever had a long webpage with validation that fails on postback but returns the user to the top of the page instead of where you want them?

Annoying isnt it. Well in .Net Framework 2.0 (yes it’s been there a while now), you can use the property:

Page.MaintainScrollPositionOnPostBack = true;

Well this will force the user to be returned back to the last point they clicked i.e. could be a control, button, checkbox etc

Very useful and helps with improving the user experience, something we should all be striving for!

Preparing an asp.net master page for print only view – stripping out css etc

Searching google turned up nothing on this so did some digging in MSDN and worked out a method of disabling all the style sheets, javascript etc to produce a text only page:

1/ Add a content block to your master page – i’ve called mine ‘cssContentHolder’

<asp:contentplaceholder id=”cssContentHolder” runat=”server”>
<link rel=”stylesheet” href=”css/master.css” type=”text/css” media=”all” />
<link href=”css/flyout.css” media=”screen” rel=”stylesheet” type=”text/css” />
<script src=”scripts/APIs/JQuery/JQuery-1.3.2.min.js” type=”text/javascript”></script>
<script src=”scripts/APIs/JQuery/Plugins/jquery-ui-1.7.1.custom.min.js” type=”text/javascript”></script>
</asp:contentplaceholder>

2/ In the markup, add a link button so the user can click it to remove the formatting

<asp:LinkButton  PostBackUrl=”#” ID=”textLink”  runat=”server” Text=”Text Only Version” onclick=”textLink_Click” ></asp:LinkButton>

3/ In the code behind, create an event handler for the button and add the following code

protected void textLink_Click(object sender, EventArgs e)
{
bool Hidden = Page.Master.FindControl(“cssContentHolder”).Visible ;
Page.Master.FindControl(“cssContentHolder”).Visible = !Hidden;
if (Hidden)
textLink.Text = “Switch to Graphical Version”;
else
textLink.Text = “Text Only Version”;
}

That’s it. When you click on the link, you will perform a postback to the server, get the state of the control and show/hide accordingly. It will also change the text so you can click back again.

Simple when you know how!

Using Javascript, another method to remove all the CSS but not update any link text etc is to call the following function:

function hideCSS(){
	if(document.getElementsByTagName){
		for(n=0;n<document.getElementsByTagName("link").length;n++){
			if(document.getElementsByTagName("link")[n].getAttribute){
				if(document.getElementsByTagName("link")[n].getAttribute("rel").indexOf("stylesheet")!=-1){
					document.getElementsByTagName("link")[n].disabled="disabled"
					}
				}
			}
		}
	}

URL Rewriting in Asp.net using URLRewriter

URL Rewriting in asp.net (c#). (Download Example Project for URL Rewriting in asp.net at the end of this article)

One way to get yourselves rated better in the search engines is to get rid of the basic aspx page and replace it with something much more descriptive i.e.:

If I were selling Nokia phones, I may have a page called http://www.mydomain.com/nokia.aspx – not much good if I am trying to target a specific phone though is it? What about this then?

http://www.mydomain.com/Nokia-E71-Mobile-Phone-With-Email-And-Internet-Browser

Much more descriptive and much more likely to get the search engines juices flowing more and hence get you rated higher in the listings.

After searching around for a few solutions, I found this article by Scott GU (Microsoft Guru Extraordinaire) http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx which got me excited.

He mentions a few methods, one of which I use on http://www.simonantony.co.uk which is running IIS7 by using the Rewrite module built into IIS – works a treat and has allowed me to convert a static html site into a more dynamic and search engine friendly version.

The other is to use a library from http://urlrewriter.net/ which is the other route I have taken. I’ve successfully implemented this on a project I am currently working upon and thought it would be nice of me to post some fully working example code that you can actually understand – the examples on the urlrewriter website/demos are very poor and not clear at all – no wonder so many people struggle to get it working.

Some blurb from the URLRewriting website will explain it more:

UrlRewriter.NET is an open-source, light-weight, highly configurable URL rewriting component for ASP.NET 1.1 and 2.0. UrlRewriter.NET provides similar IIS Rewrite capabilities that the Apache web server provides with mod_rewrite and .htaccess. You don’t need to install an ISAPI Rewrite filter to use the component. Best of all, UrlRewriter.NET is free and licensed with a very permissive MIT-style licence.

UrlRewriter.NET is a great Search Engine Optimization (SEO) tool. Using UrlRewriter.NET, you can create URL’s containing your target keywords, boosting your rankings.

With UrlRewriter.NET, you can:

* Rewrite URL’s from “user and Search Engine” friendly urls to the actual .aspx pages (also known as URL Masking, IIS Rewrite or ASP Rewrite)
* Redirect from old URL patterns to the new ones, ensuring the Search Engine spiders continue to follow your links (also known as URL Replace)
* Block certain visitors based on the User-Agent – very helpful for blocking crawlers that don’t obey the robots.txt protocol
* Ban users based on IP range (provides the capabilities of mod_rewrite on IIS)
* And much more…

UrlRewriter.NET is a pure .NET component written in C#, and does not require any ISAPI rewrite dll’s to be installed in IIS. You configure rules in a very readable XML format, either in your web.config file or an external rewriter configuration file.

UrlRewriter.NET is in use in many websites large and small such as DotNetKicks, and is embedded in several open source packages, such as the fantastic Yet Another Forum.NET.

Anyway here is how the project is constructed and how to get it working.

  1. Create a new web project – I am using C# but if you really want to you can use VB
  2. Download the urlrewriting library from the official site http://urlrewriter.net
  3. Add a reference to the UrlRewritingNet.UrlRewriter.dll to your project
  4. Open up the web.config file and replace the content with the following code:

<?xml version=”1.0″?>
<configuration>
<configSections>
<section name=”urlrewritingnet” requirePermission=”false”  type=”UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter”  />
</configSections>

<urlrewritingnet
rewriteOnlyVirtualUrls=”true”
contextItemsPrefix=”QueryString”
defaultPage=”default.aspx”
defaultProvider=”RegEx”
xmlns=”http://www.urlrewriting.net/schemas/config/2006/07″ >
<rewrites>
<add name=”this-is-a-long-page-name”  virtualUrl=”^~/this-is-a-long-page-name”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/longpage.aspx”
ignoreCase=”true” />

<add name=”Product-Search-uk”  virtualUrl=”^~/Product-Search-uk”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/search.aspx”
ignoreCase=”true” />

<add name=”submit-your-company”  virtualUrl=”^~/submit-your-company”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/submit_company.aspx”
ignoreCase=”true” />

<add name=”this-is-my-site-blog”  virtualUrl=”^~/this-is-my-site-blog”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/blog.aspx”
ignoreCase=”true” />

<add name=”contact-my-company”  virtualUrl=”^~/contact-my-company”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/contact.aspx”
ignoreCase=”true” />

<add name=”Product-Search-uk-partnumber”  virtualUrl=”^~/product(.*).aspx”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/search.aspx?id=$1″
ignoreCase=”true” />

<!–<add name=”Rewrite”  virtualUrl=”^~/(.*)/Detail(.*).aspx”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/Default.aspx?language=$1&amp;id=$2″
ignoreCase=”true” />

<add name=”RedirectInApplication”  virtualUrl=”^~/(.*)/Default.aspx”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”~/$1/Detail_Redirected.aspx”
redirect=”Application”
redirectMode=”Permanent”
ignoreCase=”true” />

<add name=”KickBrowserToDomain”  virtualUrl=”^http://(.*)/SampleWeb/kickto/(.*).aspx”
rewriteUrlParameter=”ExcludeFromClientQueryString”
destinationUrl=”http://$2?source=$1″
redirect=”Domain”
redirectMode=”Permanent”
ignoreCase=”true” />–>
</rewrites>
</urlrewritingnet>

<appSettings/>
<system.web>
<customErrors mode=”Off”>
</customErrors>
<httpModules>
<add name=”UrlRewriteModule” type=”UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter” />
</httpModules>
<compilation debug=”true” />
</system.web>
</configuration>

    • Create the aspx pages
      1. blog.aspx
      2. contact.aspx
      3. default.aspx (this should already exist)
      4. longpage.aspx
      5. search.aspx
      6. submit_company.aspx
        • In Default.aspx add the following code:

          <div id=”nav”>
          <div id=”navcontainer”>
          <ul id=”navlist”>
          <li><a href=”default.aspx”>Home</a></li>
          <li><a href=”this-is-a-long-page-name”>this-is-a-long-page-name</a></li>
          <li><a href=”Product-Search-uk”>Product Search</a></li>
          <li><a href=”submit-your-company”>Submit your company</a></li>
          <li><a href=”this-is-my-site-blog”>Blog</a></li>
          <li><a href=”contact-my-company”>Contact</a></li>
          <li><a href=”product123.aspx”>Note that this aspx page does not actually exist – click it and see what happens</a></li>

          </ul>
          </div>
          </div>

          You will notice that the href links are defined in the web.config file.

            • In search.aspx, add the following html code:

              <div>
              This is the region page – if you click on <a href=”product12345.aspx”>product12345.aspx</a>, you will be redirected here but the code will show the arguments of the page i.e. 12345 – confused? You will be!

              </div>

                • Now open up the code behind file for search.aspx and add in the Page_Load event:

                  if(Request.QueryString[“id”] != null)
                  Response.Write(“querystring passed in: ” + Request.QueryString[“id”]);
                  else
                  Response.Write(“No query string passed in”);

                    • Run the project. If you click on the search link, you will be taken to the search page but notice the URL in the browser window as it should be reading Product-Search-UK. Same for the other url’s as well except for the last one, if you click on that, a product id will be passed into the page as a querystring that you can use to display specific products on a single page – clever eh!

                      Anyway I hope this has helped you understand how to get a basic implementation of URL Rewriting in your site – i’d love to hear of any more examples you have used, if you want to post them here let me know.

                      Si

                      Download Example Project for URL Rewriting in asp.net

                      Add META keywords and Description in ASP.NET (DigitalColony.com)

                      Add META keywords and Description in ASP.NET

                      Here is the syntax for programmatically adding META tags to an ASP.NET 2.0 page.

                      HtmlMeta metaDesc = new HtmlMeta();

                      metaDesc.Name = “description”;

                      metaDesc.Content = “Tips on roasting coffee at home”;

                      Page.Header.Controls.Add(metaDesc);

                      HtmlMeta metaKey = new HtmlMeta();

                      metaKey.Name = “keywords”;

                      metaKey.Content = “roast, coffee, home, tips”;

                      Page.Header.Controls.Add(metaKey);

                      ASP.NET will render the above code to valid XHTML META tags.

                      via Add META keywords and Description in ASP.NET (DigitalColony.com).

                      Dotnet Charting

                      I was looking for some suitable dotnet charting components/code and came across the following three articles.

                      http://www.c-sharpcorner.com/UploadFile/pseabury/2DCharting11152005052210AM/2DCharting.aspx

                      http://www.c-sharpcorner.com/UploadFile/steve_hall/drawinglinechart02072007053420AM/drawinglinechart.aspx

                      http://www.c-sharpcorner.com/UploadFile/jodonnell/ChartingInGDIplus11192005063716AM/ChartingInGDIplus.aspx

                      Heres a screenshot of the one i’m using:

                      Exception Handling the nice way

                      I’ve knocked up a simple project that demonstrates a few things, namely:

                      1. Avoiding file locking issues when writing to a logfile using recursion
                      2. Dealing with Unhandled Exceptions globally
                      3. Writing this data to a local log file

                      The source code is below, feel free to download and use as you wish. If you make any improvements, please let me know. Credits to Mark bonafe for his original blog post Mark Bonafe’s Blog

                      ExceptionHandler.cs

                      using System.Collections.Generic;
                      using System.Linq;
                      using System.Text;
                      using System.Data;
                      using System.Data.SqlClient;
                      using System.Windows;
                      using System;

                      namespace WindowsFormsApplication1
                      {

                      ///
                      /// Handles displaying error messages
                      ///
                      public class ExceptionHandler
                      {
                      ///
                      /// Takes the exception message and displays a meaningful message to the user
                      ///
                      public static string DisplayMessage(Exception ex)
                      {

                      return DisplayMessage(ex, “”);
                      }

                      ///
                      /// Takes the exception message and displays a meaningful message to the user
                      ///
                      /// The exception to display.
                      /// Current User
                      //[System.Diagnostics.DebuggerStepThrough()]
                      public static string DisplayMessage(Exception ex, string userName)
                      {

                      StringBuilder sb = new StringBuilder();

                      if (ex is DBConcurrencyException)
                      sb.Append(
                      “Concurrency Error: One or more people have updated this data since your last request.”);
                      else if (ex is SqlException)
                      {
                      sb.Append(
                      “Database Error: “);
                      switch (((SqlException)ex).Number)
                      {

                      case 547:
                      sb.Append(
                      “There is a constraint on the items you tried to modify. Please try again.”);
                      break;
                      case 2601:
                      // Unique Index
                      sb.Append(“Cannot insert duplicate values into the database.”);
                      break;
                      case 2627:
                      // Unique Constraint
                      sb.Append(“Cannot insert duplicate values into the database.”);
                      break;
                      default:
                      sb.Append(ex.Message);

                      break;
                      }
                      }

                      else
                      {
                      sb.Append(
                      “Exception Handler Unexpected Error: “ + ex.Message);
                      }

                      // Show Developers extra information about the error
                      // Line numbers, StackTrace, etc.
                      {
                      {

                      string nl = “nn”;

                      sb.Append(nl + “Exception Information:” + nl);
                      sb.Append(
                      “Message: “ + ex.Message + nl);
                      sb.Append(
                      “Source: “ + ex.Source + nl);
                      sb.Append(
                      “Stack Trace: “ + ex.StackTrace + nl);

                      if (ex.InnerException != null)
                      {
                      sb.Append(nl +
                      “Inner Exception Info:” + nl);
                      sb.Append(
                      “Message: “ + ex.InnerException.Message + nl);
                      sb.Append(
                      “Source: “ + ex.InnerException.Source + nl);
                      sb.Append(
                      “Stack Trace: “ + ex.InnerException.StackTrace + nl);
                      }
                      }
                      }

                      return sb.ToString();
                      }
                      }
                      }

                      TestExceptionHandler.cs (form)

                      using System;
                      using System.Collections.Generic;
                      using System.ComponentModel;
                      using System.Data;
                      using System.Drawing;
                      using System.Text;
                      using System.Windows.Forms;
                      using System.IO;
                      using System.Threading;

                      namespace WindowsFormsApplication1
                      {

                      public class Form1 : Form
                      {
                      private LinkLabel linkLabel1;
                      private Button button1;

                      public Form1()
                      {
                      InitializeComponent();
                      }
                      [
                      STAThread]
                      static void Main()
                      {

                      Application.EnableVisualStyles();
                      Application.SetCompatibleTextRenderingDefault(false);
                      Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
                      Application.Run(new Form1());
                      }

                      private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
                      {
                      WriteExceptionToLogFile(
                      ExceptionHandler.DisplayMessage(e.Exception));
                      MessageBox.Show(ExceptionHandler.DisplayMessage(e.Exception));
                      }

                      private void InitializeComponent()
                      {

                      this.button1 = new System.Windows.Forms.Button();
                      this.linkLabel1 = new System.Windows.Forms.LinkLabel();
                      this.SuspendLayout();
                      //
                      // button1
                      //
                      this.button1.Location = new System.Drawing.Point(100, 12);
                      this.button1.Name = “button1”;
                      this.button1.Size = new System.Drawing.Size(75, 40);
                      this.button1.TabIndex = 1;
                      this.button1.Text = “Throw Exception”;
                      this.button1.UseVisualStyleBackColor = true;
                      this.button1.Click += new System.EventHandler(this.button1_Click);
                      //
                      // linkLabel1
                      //
                      this.linkLabel1.AutoSize = true;
                      this.linkLabel1.Location = new System.Drawing.Point(60, 55);
                      this.linkLabel1.Name = “linkLabel1”;
                      this.linkLabel1.Size = new System.Drawing.Size(165, 13);
                      this.linkLabel1.TabIndex = 2;
                      this.linkLabel1.TabStop = true;
                      this.linkLabel1.Text = “http://simonsteed.wordpress.com”;
                      this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
                      //
                      // Form1
                      //
                      this.ClientSize = new System.Drawing.Size(292, 75);
                      this.Controls.Add(this.linkLabel1);
                      this.Controls.Add(this.button1);
                      this.Name = “Form1”;
                      this.ResumeLayout(false);
                      this.PerformLayout();

                      }

                      ///
                      /// Uses recursion to check if the passed in filename is already locked by another process
                      /// it will continue to check to see if lock is released so that the caller can access it
                      /// It will currently only ever return true if the file is unlocked but never return false.
                      /// it would be dead easy to add a timer to this to automatically time out after a set period
                      /// unless you are happy for your app to wait until the process is finished.
                      ///
                      /// filename to check
                      /// true or false
                      private static bool IsFileUsedbyAnotherProcess(string filename)
                      {

                      FileStream fs = null;
                      try
                      {
                      fs =
                      File.Open(filename, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None);
                      }

                      catch (System.IO.IOException exp)
                      {

                      string msg = exp.Message;
                      fs.Close();
                      fs.Dispose();
                      IsFileUsedbyAnotherProcess(filename);
                      // recheck access
                      }
                      fs.Close();
                      fs.Dispose();

                      return false;
                      }

                      private static void WriteExceptionToLogFile(string msg)
                      {

                      string LogFile = “log.txt”;
                      TextWriter tw = null;
                      try
                      {
                      if (!IsFileUsedbyAnotherProcess(LogFile))
                      {

                      // create a writer and open the file
                      tw = new StreamWriter(LogFile, true);

                      // write a line of text to the file
                      tw.WriteLine(DateTime.Now + “: ‘” + Environment.MachineName + “‘ – “ + msg);
                      }
                      }

                      catch { }
                      finally
                      {
                      // close the stream
                      if (tw != null)
                      {
                      tw.Close();
                      tw.Dispose();
                      }
                      }
                      }

                      private void button1_Click(object sender, EventArgs e)
                      {

                      throw new Exception(“Test Exception”);
                      }

                      private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
                      {
                      System.Diagnostics.
                      Process.Start(“http://simonsteed.wordpress.com”);

                      }
                      }
                      }