Wednesday, September 29, 2004

ASP.NET.4GuysFromRolla.com: Dynamic Web Controls, Postbacks, and View State

Useful article on how to handle controls that are dynamically added to ASP.NET pages: ASP.NET.4GuysFromRolla.com: Dynamic Web Controls, Postbacks, and View State

Tuesday, September 28, 2004

Defending The Fox / Spread Firefox

Defending The Fox is a site that lists websites that do not support Firefox (those that suggest users to 'upgrade' to IE 5 or later. This was found on the Spread Firefox site (a site to get people to move to the Firefox browser). They succesfully achieved 2 million downloads in 10 days (very good considering the target was 1 million). Now they want 10,000 new users in 10 days.

Friday, September 24, 2004

.NET Command Prompt

This batch file allows you to do various .NET related tasks. This is useful when running under a limited user account. To do the advanced tasks you need to know the local machine administrator password. Features include:

  • Goto .NET SDK, .NET bin folder
  • Show .NET help file
  • Start Web Browser
  • Administrate folders (i.e. set permissions)
  • Administrate the computer
  • List .NET related files

DotNetCommand.cmd

@echo off
rem .NET SDK bin directory
set NetSDKBin=%NetSamplePath%bin
rem .NET bin directory
set DotNetBin=%windir%\Microsoft.NET\Framework\v1.1.4322
set PATH=%DotNetBin%;%NetSDKBin%;%PATH%
color 1f
rem goto directory as supplied (i.e. via dragging onto batch file)
cd %1
rem register doskey
doskey /insert
rem go to .NET SDK bin directory
doskey sdkdir=cd "%%NetSamplePath%%"
rem go to .NET bin directory
doskey netbin=cd "%%DotNetBin%%"
rem start Web Browser, homepage set to Google
doskey webbrowser=start http://www.google.com
rem .NET help file
doskey dotnethelp="%%ProgramFiles%%\Common Files\Microsoft Shared\Help\dexplore.exe" /helpcol ms-help://ms.netframeworksdkv1.1
rem open Windows Explorer as admin
doskey adminc=runas /u:Administrator /env "%%ProgramFiles%%\Internet Explorer\iexplore.exe c:\\"
rem open Computer Management as admin
doskey compman=runas /u:Administrator "mmc %%windir%%\system32\compmgmt.msc"
rem list c# files
doskey listcs=dir *.cs /q /p
rem list vb files
doskey listvb=dir *.vb /q /p
rem list web files
doskey listweb=dir *.as*x /q /p
rem list assembly files (dll)
doskey listdll=dir *.dll /q /p
cls
echo To goto .NET SDK directory, type: sdkdir
echo ----------------------------------------
echo To goto .NET bin directory, type: netbin
echo ----------------------------------------
echo To start Default Web Browser, type: webbrowser
echo ----------------------------------------------
echo To show .NET help file, type: dotnethelp
echo ----------------------------------------
echo To administrate folders (i.e. set permissions), type: adminc
echo  (type Control Panel in the Address bar to open the Control Panel)
echo -------------------------------------------------------------------
echo To administrate the computer, type: compman
echo -------------------------------------------
echo You can also list files and their owner
echo  (listcs, listvb, listweb, listdll)
echo ---------------------------------------
cmd.exe /e:on /f:on /k Title .NET 1.1 Command Prompt

Edit: Added ability to list .NET related files

Client-Side Validation (ASP.NET)

There is a way of getting ASP.NET to output JavaScript that works in other browsers, and it is detailed in this 4Guys article: Client-Side Validation in Downlevel Browsers. Also vote for the following bug at MSDN Labs so ASP.NET 2.0 outputs cross-browser JavaScript: Client Side Validation.

Wednesday, September 22, 2004

Entity Spaces (.NET)

Entity Spaces will become the successor to dOOdads. These are (will be in the case of Entity Spaces) .NET architectures and provide a data access layer to allow developers to interact (add, update, delete records) with any database system (Access, SQL Server, Oracle, Firebird) without needing to code for the underlying database (i.e. SQL Parameters). With these you can change your database backend without needing to change all your code (except the data access classes, which can be generated via a simply UI).

Follow the progress in Mike Griffin's Blog.

Edit (27 Sep 04): blog link update

Url Manipulation v2 (C#)

Made some improvements to the previous UrlQuery class (July 22nd, 2004). It now has a shorter way of assigning QueryString parameters:

MyQuery = new UrlQuery();
// add another parameter (or replace existing one)
MyQuery["myparam"] = "myval";
Trace.Write(MyQuery["myparam"]); // returns 'myval'
// remove parameter
MyQuery["myparam"] = null; // or string.Empty
Trace.Write(MyQuery["myparam"]); // returns ''

UrlQuery class code:

public class UrlQuery
{
	/// <summary>
	/// Base on current page
	/// </summary>
	public UrlQuery()
	{
		this.url = HttpContext.Current.Request.Url.AbsolutePath;
	}
	/// <summary>
	/// Base on other page
	/// </summary>
	/// <param name="value">The url of the page to reference, i.e.: '/path/to/folder/page.aspx?param1=1&param2=2'</param>
	public UrlQuery(string value)
	{
		int q = value.IndexOf('?');
		if (q != -1)
		{
			this.url = value.Substring(0, q);
			this.queryString = NameValueCollection(value);
		}
		else
		{
			this.url = value;
		}
	}
	/// <summary>
	/// Get and set Url parameters
	/// </summary>
	public string this[string param]
	{
		get
		{
			return this.Get(param);
		}
		set
		{
			this.Set(param,value);
		}
	}

	private string url;
	/// <summary>
	/// The Url of the page, without QueryString
	/// </summary>
	/// <value>/path/to/folder/page.aspx</value>
	public string Url
	{
		get
		{
			return this.url;
		}
	}
	/// <summary>
	/// Returns the virtual folder the page is in
	/// </summary>
	/// <value>/path/to/folder/</value>
	public string VirtualFolder
	{
		get
		{
			return this.Url.Substring(0, Url.LastIndexOf("/") + 1);
		}
	}
	/// <summary>
	/// The AbsoluteUri
	/// </summary>
	/// <value>page.aspx?param1=1&param2=2</value>
	public string AbsoluteUri
	{
		get
		{
			return this.Url + this.Get();
		}
	}
	private NameValueCollection queryString;
	/// <summary>
	/// Get the QueryString for the page
	/// </summary>
	public NameValueCollection QueryString
	{
		get
		{
			if (this.queryString != null)
			{
				return this.queryString;
			}
			else
			{
				this.queryString = new NameValueCollection(HttpContext.Current.Request.QueryString);
				return this.queryString;
			}
		}
	}
	/// <summary>
	/// Get the QueryString
	/// </summary>
	/// <returns>String in the format ?param1=1&param2=2</returns>
	public string Get()
	{
		string query = "";
		if (this.QueryString.Count != 0)
		{
			query = "?";
			for (int i = 0; i <= this.QueryString.Count - 1; i++)
			{
				if (i != 0)
				{
					query += "&";
				}
				query += this.QueryString.GetKey(i) + "=" + this.QueryString.Get(i);
			}
		}
		return query;
	}
	/// <summary>
	/// Get parameter from QueryString
	/// </summary>
	/// <param name="param">Parameter to get</param>
	/// <returns>Parameter Value</returns>
	public string Get(string param)
	{
		return this.QueryString[param];
	}
	/// <summary>
	/// Set QueryString parameter
	/// </summary>
	/// <param name="param">Parameter to set</param>
	/// <param name="value">Value of parameter</param>
	public void Set(string param, string value)
	{
		if (param != string.Empty)
		{
			if (value == string.Empty || value == null)
			{
				this.QueryString.Remove(param);
			}
			else
			{
				this.QueryString[param] = value;
			}
		}
	}
	/// <summary>
	/// Convert QueryString string to NameValueCollection
	/// http://groups.google.co.uk/groups?hl=en&lr=&ie=UTF-8&safe=off&selm=uyMZ2oaZDHA.652%40tk2msftngp13.phx.gbl
	/// </summary>
	public static NameValueCollection NameValueCollection(string qs)
	{
		NameValueCollection nvc = new NameValueCollection();
		//strip string data before the question mark
		qs = qs.IndexOf('?') > 0 ? qs.Remove(0, qs.IndexOf('?') + 1) : qs;
		Array sqarr = qs.Split("&".ToCharArray());
		for (int i = 0; i < sqarr.Length; i++)
		{
			string[] pairs = sqarr.GetValue(i).ToString().Split("=".ToCharArray());
			nvc.Add(pairs[0], pairs[1]);
		}
		return nvc;
	}
	/// <summary>
	/// Copies a form paramater to the QueryString
	/// </summary>
	/// <param name="param">Form Parameter</param>
	public void FormToQuery(string param)
	{

		this.Set(param, HttpContext.Current.Request.Form[param]);
	}
}

Tuesday, September 21, 2004

Get Firefox

Best web browser at the moment.

Get Firefox!

Tuesday, September 14, 2004

SharpDevelop 1.0 (.NET)

SharpDevelop version 1.0 is now finally out. While it doesn't do ASP.NET, it is useful for compiling .NET libraries (i.e. dll files, can be used for both Windows and Web Forms).

Wednesday, September 08, 2004

Building Web Applications with NAnt (ASP.NET)

NAnt allows you to build web applications from solution files when you do not have Visual Studio installed (or even when you do). To do so you need to install NAnt into a new directory (e.g. C:\NAnt\). After doing this add C:\NAnt\bin\ to your PATH (via System Properties, Advanced, Environment Variables, System Variables). Also add the path to the vbc/csc compilers (if not already there - C:\WINNT\Microsoft.NET\Framework\v1.1.4322\;C:\NAnt\bin\). To then compile the solution, add WebProjectName.build to the same folder as the solution (i.e. C:\Inetpub\wwwroot\WebProjectName\) and add the following to it:

<project name="WebProjectName">
	<property name="nant.settings.currentframework" value="net-1.1"/>
	<property name="Host" value="http://localhost" />
	<property name="Path" value="c:\inetpub\wwwroot" />
	<property name="WebProjectName.Host" value="${Host}/WebProjectName/WebProjectName.vbproj" />
	<property name="WebProjectName.Path" value="${Path}\WebProjectName\WebProjectName.vbproj" />
	<solution solutionfile="WebProjectName.sln" configuration="Release" >
		<webmap>
			<map url="${WebProjectName.Host}" path="${WebProjectName.Path}" />
		</webmap>
	</solution>
</project>

After saving the file, navigate to the folder using the command prompt
Start
Run
cmd
cd C:\Inetpub\wwwroot\WebProjectName\
nant.

To make things easier, you can add a Command Prompt Here (instructions, alternative download) shortcut to Windows Explorer.

Monday, September 06, 2004

Internet Explorer Hacks (CSS)

The following shows how you can hide/show CSS for certain versions of Internet Explorer (works when page is in standards mode - i.e. DOCTYPE at top of page):

mytag {
	/* all browsers */
	property: value;
	/* IE only browsers */
	_property: value;
	/* ignored by IE 5, works in IE 5.5/6 */
	property /**/: value;
	/* ignored by IE 5.5, works in IE 5/6 */
	property/**/: value;
	/* ignored by IE 6, works in IE 5/5.5 */
	property: /**/value;
	/* all browsers */
	property2: value;
	/* voice-family hack - any code after 'voice-family' not recognised by IE5/5.5 */
	voice-family: "\"}\"";
	voice-family: inherit;
	property2: newvalue;
}

CSS Filters also lists many filters for delivering certain CSS to different browsers.

Edit: CSS Filters link, more IE filtering methods - so you can serve different CSS to IE 5 / 5.5 and 6

Thursday, September 02, 2004

Generate SQL Server Views (MyGeneration) pt2

Added another template that generates a related table view (i.e. via INNER JOIN statement). Select primary/foreign table and which columns are to be in the view. Same link as before - Generate SQL Server Views.

Wednesday, September 01, 2004

Generate SQL Server Views (MyGeneration)

Added a new MyGeneration template archive that contains a template that generates views from your tables (SQL Server) - Generate SQL Server Views.

Returns NULL's if blank string and column allows NULL's. Also breaks down dates into component parts (i.e. Month, Day, Year) and to other formats:

  • Short Date (mon dd yyyy)
  • Short Time (hh:mm)
  • US Date (mm/dd/yyyy)
  • ANSII Date (yyyy.mm.dd)
  • UK Date (dd/mm/yyyy)
  • German Date (dd.mm.yyyy)
  • Italian Date (dd-mm-yyyy)

Example Output:

USE [news]
GO

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
         WHERE TABLE_NAME = 'vw_News')
   DROP VIEW vw_News
GO

CREATE VIEW [vw_News]
AS
SELECT
		[ID] AS [NewsID],
		NULLIF ([Title], '') AS [News Title],
		NULLIF ([Url], '') AS [News Url],
		[Added] AS [Date Added],
		CONVERT ( char(11) , [Added] , 113) AS [Date Added_ShortDate],
		CONVERT ( char(5) , [Added] , 108) AS [Date Added_ShortTime],
		CONVERT ( char(10) , [Added] , 101) AS [Date Added_USDate],
		CONVERT ( char(10) , [Added] , 102) AS [Date Added_ANSIIDate],
		CONVERT ( char(10) , [Added] , 103) AS [Date Added_UKDate],
		CONVERT ( char(10) , [Added] , 104) AS [Date Added_GermanDate],
		CONVERT ( char(10) , [Added] , 105) AS [Date Added_ItalianDate],
		{ fn DAYNAME ([Added])  } AS [Date Added_DayName],
		DAY ( [Added] ) AS [Date Added_Day],
		{ fn MONTHNAME ([Added])  } AS [Date Added_MonthName],
		MONTH ( [Added] ) AS [Date Added_Month],
		YEAR ( [Added] ) AS [Date Added_Year]
FROM [news]
GO
PRINT 'View Creation: vw_News Succeeded'
GO