Just in Chronicles

Life as a Voyage

Archive for the ‘Tips’ Category

Downsizing MS-SQL Server 2008 R2 Database Log

leave a comment »

When MS-SQL database files need to do backup and restore, we need to shrink the size of log file as it’s rarely necessary. In order to downsize the log file, try the following script on your MS-SQL Server Management Studio.

-- Truncate the log by changing the database recovery model to SIMPLE.
-- Shrink the truncated log file to 1 MB.
-- Reset the database recovery model.

Reference: http://technet.microsoft.com/en-us/library/ms189493.aspx

Written by Justin Yoo

05/01/2013 at 21:35

Setting Up Classic ASP Websites on IIS 7.5 with Visual Studio 2010

with 12 comments

There are still many websites built and maintained with classic ASP because of many reasons. This post will cover two topics – how to setup classic ASP websites on IIS 7.5 and how to manage codes using Visual Studio 2010.


  • OS: Windows 7 Professional SP1
  • Web Server: IIS 7.5
  • IDE: Visual Studio 2010 Professional SP1

I haven’t tested it any other than above. So, if you have a little bit different environment from mine, please bear in mind.

How to Setup Classic ASP Websites on IIS 7.5

Firstly, your IIS must turn on ASP features. Go to Control Panel > Programs and Features > Turn Windows features on or off. Then, tick the checkbox next to ASP and click OK.


Now, your IIS is able to run ASP websites. The next step is that your IIS needs a new Application Pool for the ASP websites. Go to Control Panel > Administration Tools and open Internet Information Services (IIS) Manager. Then create a new Application Pool.



Make sure that an administrator account as a Custom account for the Application Pool Identity must be selected. From the diagram above, Administrator is selected.

Once the new Application Pool is added, a new website using this Application Pool needs to be created to host classic ASP pages.


A new website for classic ASP is now created. It’s time for the website to recognise ASP script. Go to the website you’ve just created and find ASP item under the IIS section. Click it and set the below four to “TRUE“.


Once you finish the steps above, your classic ASP website should be up and running. This IIS setting also helps your Visual Studio 2010 debug the web page script.

Now, it’s time for Visual Studio 2010 to setup to manage the classic ASP codes.

How to Manage Classic ASP Codes Using Visual Studio 2010

In order for your VS 2010 to manage the classic ASP codes, three things must be done before starting to code.

First of all, register .asp file extension to your VS 2010.


This enables you to see syntax highlighting and code intellisence feature. Now, open the website by clicking File > Open Web Site…. Make sure that it’s “File System“, not anything else.



Depending on your preference, create a new solution and add a new website project under the solution. By doing so, the website will be more manageable.

Now, it’s time to create a web page. Create a new item and select an HTML Page. As a default, the filename will be HTMLPage.htm. Rename it to default.asp.



A new default.asp page is created. Type some classic ASP code into the page.


As we have already setup the syntax highlighting and code intellisense feature, in order to enjoy them, put the code <%@ Language="VBScript" %> at the first line and you will see the result like above.

Open your web browser and open the page you just created.


Please note that you can see the break point at the left next to the line number. That means we can also debug the classic ASP codes. As usual, in order to utilise the debug functions, you have to run VS 2010 as an administrator privilege. Before starting to debug, the website property must be configured.


As VS built-in web server doesn’t support classic ASP, we have to use our local IIS for debug. So, setup the property like above. And use “Attach to Process” from the Debug menu. Once you run the “Attach to Process” command, you’ll get the screen like below. Find w3wp.exe bound by the account that we setup on IIS previously (that is Administrator here in this post).


Now, try to run the website again and you’ll get the break point highlighted.


So far, we have setup and reviewed how to set up classic ASP website to run on IIS 7.5 and code it on VS 2010. By default, classic ASP is not chosen by IIS and VS 2010. So, some configuration change must be performed in order for that.

Try it and enjoy your ASP coding.

Written by Justin Yoo

12/12/2012 at 15:48

Enhanced Preview for Umbraco

leave a comment »

Existing preview function in Umbraco only supports actual pages, not contents shared within a website. This approach is logically correct as shared contents are not independent pages. However, there must be demands to preview shared contents before publishing them.

This Umbraco extension enables for content editors to preview what they have written and how the contents would be looking like, before they publish the contents.

Basic idea is simple. Umbraco provides an alternative template function by using AltTemplate querystring.

This extension allows users to assign certain document types to templates. So, when users click the preview button, this extension starts looking up the configuration values to for document type  – template mappings.

        <clear />
        <add alias="Product" template="StandardPage" redirectUrl="/products/product/{0}" />
        <add alias="Company" template="StandardPage" redirectUrl="/companies/company/{0}" />

Like the example above, the extension registers a config file, EnhancedPreviewConfiguration.config under /config/ directory. Based on this example, a document type Product will use the template StandardPage for its preview mode. After the preview, the preview page will be redirected to /products/product/[productId] page.

If you guys are interested in, please visit the following websites.

Written by Justin Yoo

31/07/2012 at 17:20

Posted in For .NET

Tagged with , ,

How to Install the Latest Version of Mercurial Web Repository on Windows 2008 Server R2

with 6 comments

It’s a super pain to install HG on Windows 2008 Server R2. This post is based on Firegarden’s article and has additional information from other resources.


  • Windows 2008 Server R2
  • The latest version of Python: 2.7.3 (at the moment of writing)
  • The latest version of PyWin32: Build 217 (at the moment of writing)
  • The latest version of Mercurial: 2.2.2 (at the moment of writing)

Setup Process

Please note that if your choice of Python has to be consistent. In other words, if you choose Python of x86 version, all other applications have to be x86 version; if you choose Python of x64 version, all other applications have to be x64 version; otherwise, this will not be working for your system.

1. Installing Python.

As Mercurial doesn’t support Python 3.x, the latest version of Python we can use is 2.7.x.

  1. Go to the Python download page. http://www.python.org/download/releases
  2. Download the latest 2.7.x version of Python. Choose the platform carefully, if to be x86 or x64.
  3. Install Python downloaded. Make sure that the installation must be conducted by an administrator permission. During the installation process, let the installer set the default installation directory, which will be C:\Python2x.
  4. Add the Python path to the system environment path.
    1. Open “Control Panel” > “System and Security” > “System” > “Advanced System Settings
    2. Click “Environment Variables...” and find the “Path” variable under “System variables” section.
    3. Append “;C:\Python2x;” to the “Path” value. Make sure that the path value is delimited by semi-colons.
    4. Open a command prompt and type “python” at any directory and you will get into the python console. Press CTRL+Z to exit from the console.
    5. If you can’t run the “python” command on the command prompt, check the step 4.3 again. If the path has been correctly set, your server might need to reboot.

2. Installing PyWin32

Again, your choice of platform has to be consistant; if you have installed Python of x86 version, this also has to be x86 version; if you have installed Python of x64 version, this also has to be x64 version.

  1. Go to the Python for Windows Extensions download page. http://sourceforge.net/projects/pywin32/files/pywin32
  2. Go to the latest build and download an appropriate one corresponding to your Python version and platform. The filename looks like “pywin32-xxx.win32-py2.7.exe”
  3. Install the PyWin32 downloaded. Make sure that the installation must be conducted by an administrator permission.
  4. In case of error you might face at the end of the installation process. The message will look like:

    close failed in file object destructor:
    sys.excepthook is missing
    lost sys.stderr

    This is because of your administrator permission. For workaround of this: http://sourceforge.net/mailarchive/message.php?msg_id=29300152

    1. Click “Start Menu” > Right click on “Computer” > Click “Manage“.
    2. Go to “System Tools” > “Local Users and Groups” > “Users
    3. Create a new account named “Admin” and assign it to the “Administrators” group.
    4. Open a command prompt as an administrator and type

      runas /user:Admin pywin32-xxx.win32-py2.7.exe

      and type password you set previously.

    5. If you get an error “Access is denied“, close the command prompt and open it again as an administrator.

3. Building and Installing Mercurial from the Source Code.

As the latest version of Mercurial installer (2.2.2 at the moment of writing) is built with Python 2.6.6, the installer will not be running on our server. So, we need to build the source with Python that we have installed into our system.

  1. Go to the Mercurial download page. http://mercurial.selenic.com/downloads
  2. Download the source code and unzip it. We assume that the unzipped directory is “C:\hg-source“.
  3. Open a command prompte as an administrator and move to the unzipped directory.
  4. Run the following command to build Mercurial

    python setup.py --pure build_py -c -d . build_ext -i build_mo --force

    Even if you meet a warning like “warning: hgbuildmo: could not find msgfmt executable, no translations will be built“, just ignore it.

  5. Run the following command to install Mercurial

    python setup.py --pure install --force

    Mercurial will have been installed at “C:\Python2x\Lib\site-packages\mercurial

  6. In order to execute to “hg” command at anywhere, try the followings:
    1. Copy “c:\python2x\scripts\hg.bat” to “c:\python2x
    2. Open hg.bat and modify the line

      "%~dp0..\python" "%~dp0hg" %*


      "%~dp0python" "%~dp0\scripts\hg" %*

4. Installing ISAPI-WSGI Module

For better performance, we need to install ISAPI-WSGI module to build a DLL file.

  1. Go to the ISAPI-WSGI download page. http://code.google.com/p/isapi-wsgi/downloads/list
  2. Download the latest version of the source code. The precompiled version will not work for our setup.
  3. Unzip it. We assume that the unzipped directory is “C:\isapi-wsgi-source“.
  4. Run the following command to compile the source

    python setup.py install

5. Seting up IIS for the Mercurial Web Repository

As IIS doesn’t recognise Python and Hg natively, we need to setup IIS manually.

  1. Open IIS Manager.
  2. Create an application pool called “Mercurial” with the following configurations:
    1. Set “.NET Framework Version” to “No Managed Code
    2. Set “Enable 32-Bit Applications” to “True“, only if you have installed x86 version of Python.
  3. Create a website on IIS for the web repository. We assume that the directory is “C:\inetpub\hg” and its URL is “hg.myserver.com“. This has to point the application pool “Mercurial“.
  4. Copy the “hgwebdir_wsgi.py” file from the Mercurial source code downloaded to “C:\inetpub\hg“. It is located in “C:\hg-source\contrib\win32“.
  5. Open the “hgwebdir_wsgi.py“, find and edit the parameters below:

    hgweb_config = r'c:\inetpub\hg\hgweb.config'
    path_prefix = 0

  6. Create a new “hgweb.config” file in “C:\inetpub\hg” and place the following into it.

    / = c:\Repositories\*

  7. Open a command prompt as an administrator and move to the directory “C:\inetpub\hg“.
  8. Run the following command to build the ISAPI-WSGI library.

    python hgwebdir_wsgi.py

  9. Open Handler Mappings and click “Add Wildcard Script Map...” with followings:
    1. Set “Executable” to “c:\inutpub\hg\_hgwebdir_wsgi.dll” that has been created from the step 5.8.
    2. Set “Name” to “Mercurial-ISAPI“.
    3. If you are asked to allow the ISAPI extension, click “YES“.

So far, if everything is done smoothly, you can browse the web repository by typing the URL “http://mg.myserver.com” into your brower’s lcation bar.

This is optional. If you want to tie basic authentication function to the web repository, try the following steps.

6. Setting up Basic Authentication of IIS onto the Web Repository

  1. Create users and a user group.
    1. Click “Start Menu” > Right click on “Computer” > Click “Manage“.
    2. Go to “System Tools” > “Local Users and Groups” > “User Groups
    3. Create a user group, named “Mercurial Users
    4. Go to “System Tools” > “Local Users and Groups” > “Users
    5. Create as many users as you want and assign the users to the “Mercurial Users” group.
  2. Set the permission for the “Mercurial Users” group to only allow the access to “C:\inetpub\hg“.
  3. Create a self-signed certificate and bind the HTTPS protocol with “hg.myserver.com“.

Once everything is done, type “https://hg.myserver.com” and you will be asked to login to the site.

It would be great if you guys who are reading this article share your experiences regardless of success or failure.

Written by Justin Yoo

02/07/2012 at 18:16

When Getting 404 Error While Using FancyBox 1.3.4 jQuery Plugin

leave a comment »

According to the article http://stackoverflow.com/questions/6591288/im-getting-404-errors-with-fancybox-images, there are 404 errors occur while using the FancyBox 1.3.4 jQuery plugin. I had the exact same errors and, because of this, my IIS has almost gone down to write server error logs.

In order to fix this issue, without modifying the plugin core, simply add the URL rewrite rule into your web.config.

				<rule name="Fancybox image path correction" stopProcessing="true">
						- the page URL is http://yoursite.com/contents/pagename.html
						- the 404 error happens when the server tries to access to http://yoursite.com/contents/fancybox/image_file_name.png
						- FancyBox jQuery plugin is located under /scripts/jquery.fancybox-1.3.4
					<match url="^contents/fancybox/(.+).png$" />
					<action type="Rewrite" url="/scripts/jquery.fancybox-1.3.4/fancybox/{R:1}.png" />

Node that this is just a workaround, not the solution. The best thing is modifying the plugin core.

Written by Justin Yoo

10/05/2012 at 12:37

Posted in For Web

Tagged with , ,

Removing the “x_” Prefixes Injected by AntiXSS Library, from the “id” and “class” Attributes

leave a comment »

Microsoft Web Protection Library provides strong security protection while building a web site. By using this library, the web site can avoid XSS attacks. One of the benefits using this library is that the web site can sanitise users’ input, that means the HTML input can be filtered by the library.

However, during the sanitisation process, a prefix, "x_", intentionally prepends both "id" and "class" attributes of each HTML element. The reason is that the sanitisation process cannot guarantee which "id" and "class" values are safe or not, so each "id" and "class" attribute have their prefix "x_" as a result. This is, of course, not desirable. So, developers have to get rid of those prefixes from the HTML output.

public static string RemoveSanitisedPrefixes(string html)
	Match match = Regex.Match(html, "(id|class)=\"?(x_).+\"?", RegexOptions.IgnoreCase);
	if (match.Success)
		string key = match.Groups[2].Value;
		html = html.Replace(key, "");
	return html;

Once your HTML contents are sanitised by Microsoft.Security.Application.GetSafeHtml() or Microsoft.Security.Application.GetSafeHtmlFragment(), pass the sanitised HTML value to the method above, and you’ll get the "x_" removed HTML contents.

Written by Justin Yoo

16/04/2012 at 13:25

Quiz: 3-6-9 Game with Your Programming Language

leave a comment »

There is a very popular game in Korea, called “3-6-9”. Its rule is very simple:

  • A player starts counting from 1.
  • Next player count the number added 1. Repeat this rule until one player fails counting.
  • However, when a player meets a number containing digits such as 3, 6, or 9, the person has to do a clap for the number of times.
  • This is the example of playing:
    • 1, 2, “clap” (3), 4, 5, “clap” (6), 7, 8, “clap” (9), 10, 11, 12, “clap” (13), 14, 15, “clap” (16), 17, 18, “clap” (19), 20, 21, 22, “clap” (23), 24, 25, “clap” (26), 27, 28, “clap”  (29), “clap” (30), “clap” (31), “clap” (32), “clap clap” (33), “clap” (34), “clap” (35), “clap clap” (36), “clap” (37), “clap” (38), “clap clap” (39), 40, 41, 42, “clap” (43), …

The question is…

Use your preferred programming language, create a function or method to perform this game up to 100.

And my solution using C# is… (substituted “clap” with “X”)

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Aliencube.Quizes
	public partial class ThreeSixNine
		public static string Execute(int maxNumber = 100)
			List<string> results = new List<string>();
			for (int i = 1; i <= maxNumber; i++)
				int xs = Regex.Matches(Convert.ToString(i), "[369]").Count;
				results.Add(xs == 0 ? Convert.ToString(i) : new String('X', xs));
			return String.Join(" ", results);

How’s yours guys?

Written by Justin Yoo

15/04/2012 at 18:36

Posted in For .NET

Triming Property Type Value – Description or Validation – While Saving Document Type in Umbraco

leave a comment »

When developers create a document type in Umbraco, they might notice that an extra line – either Line Feed (\n) or Carriage Return (\r), or both – is added into those two fields – Validation and Description – of each property. This extra white space will result in validation errors and prevent the content from saving, in the Content section.

In order to avoid this, the value must be trimmed while retrieving and saving by modifying the source code, UmbracoProject\umbraco\cms\businesslogic\propertytype\propertytype.cs. Find the following code lines from the file and put .Trim() as highlighted.

public string ValidationRegExp
	get { return _validationRegExp.Trim(); }
		_validationRegExp = value.Trim();
			"Update cmsPropertyType set validationRegExp = @validationRegExp where id = @id",
			SqlHelper.CreateParameter("@validationRegExp", value.Trim()), SqlHelper.CreateParameter("@id", Id));
public string Description
		if (_description != null)
			if (!_description.StartsWith("#"))
				return _description.Trim();
				Language lang = Language.GetByCultureCode(Thread.CurrentThread.CurrentCulture.Name);
				if (lang != null)
					if (Dictionary.DictionaryItem.hasKey(_description.Substring(1, _description.Length - 1)))
						var di =
							new Dictionary.DictionaryItem(_description.Substring(1, _description.Length - 1));
						return di.Value(lang.id).Trim();

			return "[" + _description.Trim() + "]";

		return _description.Trim();
		_description = value.Trim();
			"Update cmsPropertyType set description = @description where id = @id",
			SqlHelper.CreateParameter("@description", value.Trim()),
			SqlHelper.CreateParameter("@id", Id));
public string GetRawDescription()
	return _description.Trim();

By adding the .Trim() method, even though it can’t prevent displaying an extra line, but it won’t save the extra line into the database.

Written by Justin Yoo

27/03/2012 at 18:12

uComponents: Multi-Node Tree Picker Data Saving Format Error in Umbraco

leave a comment »

uComponents is a killer extension for Umbraco as it compliments a lot of features that Umbraco lacks or doesn’t have. Nowadays uComponents is a sort of de-facto standard extension because many other extensions are assuming that uComponents is installed.

Once uComponents is installed, several data types used in Umbraco are also installed. Multi-Node Tree Picker (MNTP) which is one of the installed data types is, I believe, the most useful and versatile data type. However, it stores its value as NTEXT type when its value type is set to CSV, which is not quite right.

When you modify contents at the Umbraco back-office, the following error message can be seen.

Your data has been saved, but before you can publish this page there are some errors you need to fix first:

  • [PROPERTY] at [TAB] is not in a correct format

This results from the fact that the value type is set to NTEXT, instead of NVARCHAR. So, once a data type using MNTP is created, the value type should be updated to NVARCHAR directly in SQL.

	cmsDataType AS dt
	JOIN umbracoNode AS node
		ON dt.nodeId = node.id
	dt.controlId = 'c2d6894b-e788-4425-bcf2-308568e3d38b'

Note that the controlId has the value “c2d6894b-e788-4425-bcf2-308568e3d38b” that represents MNTP. Once the query is run, all MNTP data types are listed. They all have NText at their dbType. So they need to be updated to NVarchar by running the following SQL script.

	dbType = 'Nvarchar'
	controlId = 'c2d6894b-e788-4425-bcf2-308568e3d38b'

Now, the MNTP control will have NVarchar data value and will not display the error message above.

Written by Justin Yoo

26/03/2012 at 13:56

How to Get List of Countries Defined in ISO 3166-1 Programatically by C#

with 3 comments

ISO 3166-1 defines the list of countries currently existing in the world while ISO 639-1 defines the list of languages currently and officially used all over the world. What if we need to display the list of countries do developers usually try? We can think of creating a meta table in a database or an XML file for reference.

Fortunately, .NET framework provides System.Globalization namespace to handle culture specific data such as date and time format, currency format and so forth. This is particularly useful for applications considering I18N or L10N.

There are two classes called CultureInfo and RegionInfo in the System.Globalization namespace. CultureInfo detects current system environment and returns the current culture including language, country, currency, time and date. It also returns a specific culture information by manually initialising the culture code. A CultureInfo object contains both language code defined by ISO 639-1 and country code defined by ISO 3166-1. By using this information, we can programmatically returns the list of countries.

/// <summary>
/// Gets the list of countries based on ISO 3166-1
/// </summary>
/// <returns>Returns the list of countries based on ISO 3166-1</returns>
public static List<RegionInfo> GetCountriesByIso3166()
	List<RegionInfo> countries = new List<RegionInfo>();
	foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures))
		RegionInfo country = new RegionInfo(culture.LCID);
		if (countries.Where(p => p.Name == country.Name).Count() == 0)
	return countries.OrderBy(p => p.EnglishName).ToList();

Let’s see the highlighted line 8 above. Firstly, we need list up all cultures and create RegionInfo objects based on the culture. As a CultureInfo object has both language code and country code and some CultureInfo objects have common country code, eg. en-CA (English in Canada), fr-CA (French in Canada), we need to take only one RegionInfo object (line 10-12).

/// <summary>
/// Gets the list of countries by selected country codes.
/// </summary>
/// <param name="code">List of culture codes.</param>
/// <returns>Returns the list of countries by selected country codes.</returns>
public static List<RegionInfo> GetCountriesByCode(List<string> codes)
	List<RegionInfo> countries = new List<RegionInfo>();
	if (codes != null && codes.Count > 0)
		foreach (string code in codes)
				countries.Add(new RegionInfo(code));
				//	Ignores the invalid culture code.
	return countries.OrderBy(p => p.EnglishName).ToList();

We can also get the list of countries from the country codes provided like above. Make sure that we need to use the try...catch... block (line 19) to ignore the invalid country code used. This code can be more improved by using various types of codes.

Written by Justin Yoo

15/03/2012 at 08:00