Saturday, May 2, 2009

Google Chrome and XABP applications

If like me you don’t use Internet Explorer you will need this little tip. In order to get WPF applications to work in Google Chrome; simply add this to your PATH environment variables.

c:\Program Files\Mozilla Firefox

Thursday, April 30, 2009

Fix to install .Net 3.5 on Windows Server 2008 - 80073712

I have spent about four frustrating hours trying to get my Server 2008 to have the latest .Net on it. After trying to install the dontnetfx35.exe manually and it failing and reading the Microsoft blog that I should install a hot fox and if that failed I should repair my whole installation. So dutifully I did this; still the same problem!!

So I stuck with it and followed the “System Update Readiness Tool” and let it scan my component store. Whilst it was doing this I learnt about the new way that Vista and Server 2008 handle OS updates here. After the tool had run I followed the instructions and looked in the log files for any errors and low and behold it told me that it was missing a manifest with wcf, which I thought would be the reason why it could not install the latest .Net.

After reading Aaron’s blog “Steps I use to narrow down an OS update installation failure on Windows Vista and higher”, I looked at all of the logs and found that mine was failing because it stated that

DepCheck indicates Microsoft .NET Framework 2.0SP1 (x86) (CBS) is not installed

So armed with this looking in the registry (from Aarons post), I find the missing package that should have installed the wcf manifest and it gives me a Microsoft Knowledge Base (KB958481). Now I need to install MSU into Windows 2008 as it is not liking the MSI’s as they have blocks in them in order to check what version they are being installed on. But if you look at this update for dotnetfx35 you will see that it is made up of three separate updates – one of them .Net 2.0 which I need. You can download this here. So I install these two standalone patches and re-run the CRU check (1st stage). It has removed my six missing dotnet manifests, but added a whole bunch of new ones!

I need .Net 3.5 on this machine as I want to put SQL Server on this machine and I am getting frustrated as this has been about 6 hours! Then a brainwave, what about the Visual Studio WCU (Windows Component Update), so I stick the Visual Studio 2008 DVD and navigate to

The best resource I found for Server 2008 setup steps

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

 

Ok – After all of this – the simple thing to prevent all of this is not to setup IIS before you have installed the dotnet3.5 service pack on Windows Update. I found the best way to solve all of this was to just re-install the operating system. Leave it running over night and INSTALL WINDOWS UPDATES as the very first thing

TFS 2008 problem creating Team Project. TF30171

I was attempting to create a new Team Project in TFS and it would not let me TF30177. So I realised I had an orphan project laying around.

How to delete a Team Project from TFS 2008 from TFS which was fine, but I still had the Sharepoint project. So here is how to get rid of that too.

Monday, April 27, 2009

TFS 2008 SP1, WSS3.0 SP1 and SQL Server Express 2008 on Windows 2008 – Won’t work!

  • TFS 2008 SP1 will not work with SQL Express 2008 as Express does not have Agent enabled.
  • You cannot upgrade from Express 2008 to the Standard 2008 as the setup program uses the shell of the installed instance. Instead you have to remove all instances (you can leave the shared tools installed) and then re-run setup from you Standard 2008 setup program
  • When TFS 2008 SP1 installs it assumes that your Analysis Service is on the default sql instance – mine wasn’t. You will need this to change your TFS setup to work.
  • It’s always wise to check that your client is Sql 2008 when you decide to install your server with no interface. I decided to have a light weight server and then had to upgrade my laptop as SQL Server 2005 obviously can’t connect to SQL Server 2008.
  • SQL Server 2008 shared tools need SP1 of Visual Studio installed!
  • You need over 3GB to install the Service Pack and that isn’t going to happen when you only have 2Gb free

What a bloody brilliant afternoon today has been!

Saturday, April 25, 2009

Sql Server 2008 and Windows Server Core 2008

I have just spent a few happy days investigating Server Core and was looking forward to have a clean OS with no Internet Explorer. However I never realised that .Net would be able to be installed on this version of the Operating System. How crazy is that?!?! So you can have a nice IIS webserver running PHP, but then not run ASP.NET apps? That is ludicrous!

For more info: http://blog.namwarrizvi.com/?p=152

Backing up new Server 2008 Core – missing wbadmin

Whilst I was playing with this server, I was interested in having a baseline image of my server as I played with the new features. However everything I read said that I could use WBADMIN to run a backup. I typed it from the command line and it wasn’t there!

So whilst doing some searching about IIS I came across the solution. I saw this post about Role Management Tool.

So I ran

ocsetup WindowsServerBackup



Once the Component setup has installed it you can now use WBADMIN



wbadmin start systemstatebackup –backuptarget:e

Windows Server Core 2008: First steps - configuring for remote desktop

From a previous post you will see that I destroyed all my servers and started to learn something about Windows 2008. So now my new 2x512Mb RAM sticks have arrived for my K7N420 Pro Motherboard. Now I could load Windows 2008 on it as the minimum is 512Mb RAM for this OS. I thought let’s install the new “Server Core System”, which to be fair was extremely quick to install and had me with a log on screen quite quickly.

However, I log in, change the password (its blank as default) and then suddenly release I don’t even have a GUI. Cool I thought, I only want this server to run a DB and TFS Server. So let’s configure it.

1) Let’s give it a name, type the following in the command window

hostname



which should give you something daft like




win-egmik5j3f4m




Not exactly the best machine name, so type the following (where Simain is going to be my machine name). I always like to reboot after a name change (old habits!)



netdom renamecomputer win-egmik5j3f4m /NewName:Simian /REBoot





2) Next I check the network settings so that I can use the GUI of my laptop, so I check the settings



ipconfig /all


and notice that there are no IP addresses or no network configured at all. So next lets see what interfaces are defined.



netsh interface ipv4 show interfaces



So this tells me I have “Local Area Connection” and some Loopback pseudo interface. Make a note of the index of your interface as you will need it later



Now I assume that I need to configure the Local Area Connection as it states it is DHCP, and I wanted my server to have a static IP.



netsh interface ipv4 set address name="Local Area Connection" 


source=static address=192.168.2.2 mask=255.255.255.0 gateway=192.168.2.1



After this the ‘DHCP Enabled’ setting in ipconfig /all has changed to No. So the next step is to add the DNS, for this you need the index from earlier



netsh interface ipv4 add dnsserver name="Local Area Connection" address=192.168.2.1 index=2


Now all I have to do is change my DHCP server to give out IP from a range of 3 onwards, so that I never get a conflict.



So, now I have a machine on the network, I want to unplug all the peripherals and connect to it via Remote Desktop (mstsc). Let’s tell the registry and the firewall to allow remote desktop connections.



cscript C:'Windows'System32'Scregedit.wsf /ar 0


netsh advfirewall firewall set rule group="Remote Desktop" new enable=yes



Now I can use my server like a true remote server on my network.



For further information please see here.

Windows Server Core 2008 – 3Com NIC installation problem

It appeared that my on-board NIC was not working as my new installation would not recognise it. So I took my “3C905C-TX-M Etherlink 10/100BT PCI NIC w/Management” from a server that was running Server 2003 and I knew was working. Plugged it in and it still did not recognise this one.

Now the Vista drivers are different so I tried to download some drivers on the net, I copied them onto the new server and ran the exe. Still didn’t recognise the NIC after a reboot. So I went to the extracted location of the R41104.exe and navigated to

Bare in mind that this exe tries to extract the drivers to a Dell Location. Mine is not a Dell, so I extracted them to a “Drivers” folder.

x:\Drivers\R41104\Windows\Update\Source

Then type in the following command.

pnputil –i –a W9X90XBC.INF

My network is all up and running. I might go and see if this works with the on board nForce NIC

Windows 2008 Server install problems - 0x800706F8

“Windows cannot install required files. Make sure all files required for installation are available, and restart the installation. Error code: 0x800706F8”

I originally installed Server 2008 from XP and installed it on a different partition and everything worked fine. However, I nuked the machine as I wanted to get rid of the XP Partition and I accidently lost the MBR (Master Boot Record).

So after trying to install Vista directly from the DVD. I kept getting the message above.

After a lot of research it ended up being that a Samsung SD-604 DVD has problems without the correct device drivers. However it was not listed here.

So the trick is to boot off the DVD and get to Boot Strap to recognise all your drives. Then say that you are going to repair your machine and navigate to the Command Prompt. Copy the DVD onto a folder called E:\Windows2008Setup and then install it from this command prompt.

Some other useful things I learnt were

Thursday, April 9, 2009

Creating a backup plan for SQL Express

Sql Server 2008 Express does not come with the built in agent that most servers do. I have a simple E-Commerce shopping cart system and I have decided to use SQL Server Express as it is free for single processor machines and I don’t need anything fancy – just a simple DB to be honest.

So here is how to have a database backup plan.

http://code.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=ExpressMaintenance

which was utter rubbish and his examples don’t even run!

So try this

http://www.sqldbatips.com/showarticle.asp?ID=27

Which is one stored procedure and then a Windows Task to call it every week. Prefect. Exactly what I needed. When I get a spare moment, I am going to look at this one as I want to learn PowerShell

http://www.databasejournal.com/features/mssql/article.php/3693606/Microsoft-Windows-PowerShell-and-SQL-Server-2005-SMO--Part-6.htm

Saturday, March 28, 2009

Getting rid of GoogleUpdater

Google Updater is installed when you install any Google product. It then sits in the background and checks for updates. I don’t want it to on my server. I wanted a browser that wasn’t IE 6.0 and I didn’t want the bloat ware of IE 8.0. So I installed Google Chrome as a light weight browser, that would not constantly require Microsoft Updates.

So how do you get rid of the Google Updater?

1) Go to Scheduled Tasks.

  • Either by Control Panel –> Scheduled Tasks
  • Explorer –> Windows –> Tasks

2) You will see the Google Updater sat there. It will start a process when the processor is Idle for 10 mins. Just delete this task and Google wont update anymore.

Thursday, March 19, 2009

Rebuilding all my Personal Computers

I had some time off work, so I decided to rebuild all those old machines I had in the spare room. I had the following: -

I initially thought that I could take the disks out of the P6DBS and undo the Caddy and just copy the data onto my laptop. I forgot the old IDE vs SCSI differences (http://www.mindconnection.com/library/computertips/ide-scsi.htm). But I was reminded about the beauty of SCSI and the way you can just “span” disks together to be seen as one by the operating system.

I stole the memory from the 6BTA3 to boot the P6DBS. I noticed that although it had 5 HDD, it only had power cables for 4 devices. So the first step was to copy all the data onto my Western Digital My Book (http://support.wdc.com/product/spec.asp?groupid=110&lang=en&print=y) I always thought 1 Tb of data was overkill, but I am slowly filling it!

After I had copied 16Gb of data of 2 of the drives, I noticed that my P6DBS was a dual processor motherboard, I decided to take the Pentium III out of the 6BTA3 and plug it in. It worked! It just said that I had 2x Pentium II. Oh well, wasn’t even expecting it to work to be honest! Then the first mistake – flashing the BIOS!!!

I went to SuperMicro (http://www.supermicro.com/support/bios/archive.cfm) site to get a new BIOS and used (http://www.bootdisk.com/) to create a Boot disk. Well that completely fried my machine and it constantly beeped after turning it on. Which according the web was the Power Unit failing (http://www.wimsbios.com/faq/solveamibiosbeepcodes.jsp). So I ripped the Power Supply Unit (PSU) out of the 6BTA3 (that ATX case was just a motherboard now!) and used that. This made the constant beeps turn into 7 beeps (apparently the graphics card was now not seated), and after taking out the memory it had a different number of beeps! So I thought, I need to recover the BIOS.

I followed this (http://www.wimsbios.com/faq/howtorecoveracorruptbios.jsp) guide and ended up setting the motherboard jumper and even took the CMOS battery out and left it over night (was 3am by now!). By this time frustration made me read the manual and release that I should have renamed the backed up BIOS (super.rom). I wish I had followed the instructions to the letter!!

So now I had no way off renaming the rom file as I needed to boot the P6DBS and hold down CTRL and HOME with the floppy disk in and it should reflash the drive reading the super.rom file.

So onto destroying the other machine so that I could use the floppy drive!

More to come . . . .

http://neosmart.net/wiki/display/EBCD/Recovering+the+Vista+Bootloader+from+the+DVD

http://neosmart.net/blog/2008/windows-vista-recovery-disc-download/

http://isorecorder.alexfeinman.com/v2.htm

Wednesday, March 18, 2009

ConfigurationSection that reports missing sections in config

It has long annoyed me taken other frameworks that need config sections defined and spending the time copying the sections over, it would be so much easier if the Framework told you what bit of configuration it was trying to load. So I always use this abstract class for all of my config sections.

public abstract class SimianConfigurationSection : ConfigurationSection
{
/// <summary>
///
Gets the section.
/// </summary>
/// <param name="definedName">
Name of the defined.</param>
/// <returns></returns>
public static ConfigurationSection GetSection(string definedName)
{
ConfigurationSection section = ConfigurationManager.GetSection(definedName) as ConfigurationSection;

if (section == null)
throw new ConfigurationErrorsException("The <" + definedName +
"> section is not defined in your .config file!");

return section;
}
}


Next derive from this class rather than the .Net Framework class. e.g.



public class EmailTemplatesSection : SimianConfigurationSection



Once this has been completed your application will report a simple configuration exception if it cannot find your section in the config file. This takes 5 minutes to implement, but helps so much when you are configuring frameworks.



This then allows a really simple pattern when you want your configuration section.



return DBCategoryProviderSection.GetSection("nopDataProviders/CategoryProvider") as DBCategoryProviderSection;

You will no longer get an “Object is not a reference . . . “ exception.

Monday, March 16, 2009

Json Extension methods

Extension methods are so cool in your web layer so that you can easily convert your things between Json and your object. All you have to do now is decorate your classes with the DataContract/DataMember attributes. How simple is that?

public static class JsonHelper
{
/// <summary>
///
Converts any object to a JSON string
/// </summary>
/// <param name="value">
The value.</param>
/// <returns></returns>
public static string ToJson(this object value)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(value.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, value);
return Encoding.Default.GetString(ms.ToArray());
}
}

/// <summary>
///
Deserializes the specified json.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">
The value.</param>
/// <returns></returns>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
public static T FromJson<T>(this string value)
{
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(value)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(ms);
}
}
}

Wednesday, February 25, 2009

Preparation Guide for 70-564 Exam. Designing and Developing ASP.NET Applications Using the Microsoft .NET Framework 3.5

Designing and Implementing Controls For 70-564 Exam (13 percent)

Choose appropriate controls based on business requirements.
May include but is not limited to: user controls, server controls, built-in controls, custom controls, third-party controls, Web parts
Design controls for reusability.
May include but is not limited to: user controls, server controls, inheritance for changing behavior
Manage states for controls.
May include but is not limited to: control state, view state, accessing form elements
Leverage data-bound controls.
May include but is not limited to: use gridviews, use sorting and paging callbacks when available, when to use custom sorting and paging, server-side pagination
Choose appropriate validation controls based on business requirements.
May include but is not limited to: server-side page validation (Page.IsValid), custom validator, validation groups, validation summary
Identify the appropriate usage of ASP.NET AJAX.
May include but is not limited to: implementing partial page updates with update panel, using ASP.NET AJAX controls, script services
Manage JavaScript dependencies with server controls.

Designing the Presentation and Layout of an Application For 70-564 Test (16 percent)


Design complex layout with Master Pages.
May include but is not limited to: strongly typed master pages, nested master pages
Plan for various user agents.
May include but is not limited to: markups for different browsers for mobile devices, screen readers, accessibility
Design a brandable user interface by using themes.
May include but is not limited to: shared themes across multiple applications, run time master page selection
Design site navigation.
May include but is not limited to: when to extend site map provider, treeview menu vs. site map path, programmatically manipulating site map nodes, overriding menu rendering by using control adapters, filtering site map nodes based on user roles
Plan Web sites to support globalization.
May include but is not limited to: custom resource provider vs. resource files, localize applications

Accessing Data and Services For 70-564 Test (18 percent)


Plan vendor-independent database interactions.
May include but is not limited to: IDBconnection, IDBcommand, IDBadapter, IdataReader, Datareader vs. dataset
Identify the appropriate usage of data source controls.
May include but is not limited to: SQLDataSource, ObjectDataSource, XMLDataSource
Leverage LINQ in data access design.
May include but is not limited to: LINQtoSQL, lambda expressions, LINQtoObjects, LINQtoXML
Identify opportunities to access and expose Web services.
May include but is not limited to: WCF, ASMX, REST

Establishing ASP.NET Solution Structure For 70-564 Test (13 percent)


Determine when to use the Web Site model vs. a Web Application Project.
May include but is not limited to: project file, references, namespace, user profile object, precompilation
Establish an error-handling strategy.
May include but is not limited to: Global.asax events, Web.config elements, TRY/CATCH blocks, error logging
Manipulate configuration files to change ASP.NET behavior.
May include but is not limited to: machine key, tracing, encrypting Web configuration data, custom configuration sections
Identify a deployment strategy.
May include but is not limited to: mangement application pools, Web deployment projects, pre-compilation, custom action classes

Leveraging and Extending ASP.NET Architecture For 70-564 Exam (17 percent)


Design a state management strategy.
May include but is not limited to: Cache, ViewState, Application object, Session object, cookies, cookieless session
Identify the events of the page life cycle.
May include but is not limited to: appending controls, PostBack model, accessing state, data binding
Write HttpModules and HttpHandlers.
May include but is not limited to: URL rewriting, SSO application, dynamically retrieve data
Debug ASP.NET Web applications.
May include but is not limited to: debug JavaScript, tracing, debug tools in IDE, examining HTTP headers
Plan for long-running processes by using asynchronous pages.
May include but is not limited to: AddonPreRenderCompleteAsync, RegisterAsyncTask

Applying security principles For 70-564 Exam (23 percent)


Identify appropriate security providers.
May include but is not limited to: membership, role, profile, extending custom providers
Decide which user-related information to store in a profile.
May include but is not limited to: create user profile properties, extend membership objects, custom types
Establish security settings in Web.config.
May include but is not limited to: identity/impersonation, authentication, authorization (location nodes in Web.config)
Identify vulnerable elements in applications.
May include but is not limited to: SQL injection, cross-site scripting, protecting against bots
Ensure that sensitive information in applications is protected.
May include but is not limited to: hash and salt passwords, encrypting information

Tuesday, February 17, 2009

Preparation Guide for Exam 70-562

Skills measured by Exam 70-562

Configuring and Deploying Web Applications (10 percent)

Configure providers.
  • May include but is not limited to: personalization, membership, data sources, site map, resource, security
  • Configure authentication, authorization, and impersonation.
  • May include but is not limited to: Forms Authentication, Windows Authentication
    • Configure projects, solutions, and reference assemblies.
    • May include but is not limited to: local assemblies, shared assemblies (GAC), Web application projects, solutions
    Configure session state by using Microsoft SQL Server, State Server, or InProc.
  • May include but is not limited to: setting the timeout; cookieless sessions
    • Publish Web applications. May include but is not limited to:
    • FTP
    • File System
    • or HTTP from Visual Studio

    Configure application pools.

    Compile an application by using Visual Studio or command-line tools. May include but is not limited to:
  •  aspnet_compiler.exe
  • Just-In-Time (JIT) compiling
  •  aspnet_merge.exe
  • Consuming and Creating Server Controls (20 percent)

    Implement data-bound controls. May include but is not limited to: DataGrid, DataList, Repeater, ListView, GridView, FormView, DetailsView, TreeView, DataPager

    Load user controls dynamically.

    Create and consume custom controls. May include but is not limited to: registering controls on a page, creating templated controls
    Implement client-side validation and server-side validation. May include but is not limited to: RequiredFieldValidator, CompareValidator, RegularExpressionValidator, CustomValidator, RangeValidator
    Consume standard controls. May include but is not limited to: Button, TextBox, DropDownList, RadioButton, CheckBox, HyperLink, Wizard, MultiView

    Working with Data and Services (17 percent)

    Read and write XML data. May include but is not limited to: XmlDocument, XPathNavigator, XPathNodeIterator, XPathDocument, XmlReader, XmlWriter, XmlDataDocument, XmlNamespaceManager

    Manipulate data by using DataSet and DataReader objects.

    Call a Windows Communication Foundation (WCF) service or a Web service from an ASP.NET Web page. May include but is not limited to: App_WebReferences; <system.serviceModel> configuration
    Implement a DataSource control. May include but is not limited to: LinqDataSource, ObjectDataSource, XmlDataSource, SqlDataSource

    Bind controls to data by using data binding syntax.

    Troubleshooting and Debugging Web Applications (16 percent)
    Configure debugging and custom errors. May include but is not limited to: <customErrors mode="Off|On|RemoteOnly" />, <compilation debug="true"/>

    Set up an environment to perform remote debugging.

    Debug unhandled exceptions when using ASP.NET AJAX. May include but is not limited to: client-side Sys.Debug methods; attaching a debugger to Windows Internet Explorer
    Implement tracing of a Web application. May include but is not limited to: Trace.axd, Trace=True on @Page directive,<trace enabled="true"/>
    Debug deployment issues. May include but is not limited to: aspnet_regiis.exe; creating an IIS Web application; setting the .NET Framework version
    Monitor Web applications. May include but is not limited to: health monitoring by using WebEvent, performance counters

    Working with ASP.NET AJAX and Client-Side Scripting (15 percent)

    Implement Web Forms by using ASP.NET AJAX. May include but is not limited to: EnablePartialRendering, Triggers, ChildrenAsTriggers, Scripts, Services, UpdateProgress, Timer, ScriptManagerProxy
    Interact with the ASP.NET AJAX client-side library. May include but is not limited to: JavaScript Object Notation (JSON) objects; handling ASP.NET AJAX events

    Consume services from client scripts.

    Create and register client script. May include but is not limited to: inline, included .js file, embedded JavaScript resource, created from server code

    Targeting Mobile Devices (5 percent)

    Access device capabilities. May include but is not limited to: working with emulators
    Control device-specific rendering. May include but is not limited to: DeviceSpecific control; device filters; control templates
    Add mobile Web controls to a Web page. May include but is not limited to: StyleSheet controls; List controls; Container controls
    Implement control adapters. May include but is not limited to: App_Browsers; rendering by using ChtmlTextWriter or XhtmlTextWriter

    Programming Web Applications (17 percent)

    Customize the layout and appearance of a Web page. May include but is not limited to: CSS, Themes and Skins, Master Pages, and Web Parts, App_Themes, StyleSheetTheme
    Work with ASP.NET intrinsic objects. May include but is not limited to: Request, Server, Application, Session, Response, HttpContext
    Implement globalization and accessibility. May include but is not limited to: resource files, culture settings, RegionInfo, App_GlobalResources, App_LocalResources, TabIndex, AlternateText , GenerateEmptyAlternateText, AccessKey, Label.AssociatedControlID
    Implement business objects and utility classes. May include but is not limited to: App_Code , external assemblies

    Implement session state, view state, control state, cookies, cache, or application state.

    Handle events and control page flow. May include but is not limited to: page events, control events, application events, and session events, cross-page posting; Response.Redirect, Server.Transfer, IsPostBack, setting AutoEventWireup

    Implement the Generic Handler.

    Tuesday, February 10, 2009

    Structs and Anonymous backing fields

    I got this error today

    Backing field for automatically implemented property must be fully assigned before control is returned to the caller.

    I found a strange thing out today in connection with Structs and anonymous fields. I wanted something simple like

    public struct Person
    {
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public Int16 Age { get; set; }

    public Person(String firstName, String lastName, Int16 age)
    {
    FirstName = firstName;
    LastName = lastName;
    Age = age;
    }
    }


    well that won’t compile as you will need to initialise all of the fields, so you have to do this – notice the call to the default constructor.



    public struct Person
    {
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public Int16 Age { get; set; }

    public Person(String firstName, String lastName, Int16 age): this()
    {
    FirstName = firstName;
    LastName = lastName;
    Age = age;
    }
    }

    Maybe the compiler should not allow anonymous fields in structs?

    Monday, February 9, 2009

    UK Common regular expressions

    I thought I would share my ideas on regular expressions. What I don’t like about the RegularExpressionValidator is that you have to repeat your regular expressions over and over again. It would be so much better if you could place them in a single place. So I thought I would write about a solution I came up with a few years ago. So the first part is the list of Regular Expressions. I like the idea of putting them in their own config file.

    The section allows us to have our own class that represents regular expressions. The interesting parts of the regular expressions are

    • The & is represented as a a escaped &amp; as it is in XML
    • We only have to define things like FirstName once and if the customer changes their mind, we change it in one place.
    • The password is minimum of 6 in length and must have an upper case, a lower case and one digit.
    • Most of the regular expressions allow for é and á and various other common accents
    • The post code has gone through lots of testing with customers and is the best I have found.
    • The phone numbers are UK
    <regexSection>
    <
    regularExpressions>
    <
    regexConfig name="Password" value="^.*(?=.{6,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$" />
    <
    regexConfig name="FirstName" value="^[a-z A-Z \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,50}$" />
    <
    regexConfig name="LastName" value="^[a-z A-Z \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,50}$" />
    <
    regexConfig name="PhoneNumber" value="^(?=.{10,13}$)0([0-9] ?){8,9}[0-9]$" />
    <
    regexConfig name="MobilePhoneNumber" value="^(?=.{11,13}$)07([0-9] ?){8}[0-9]$" />
    <
    regexConfig name="Email" value="(?i)^[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|biz|info|name|aero|jobs|museum|asia|edu)\b" />
    <
    regexConfig name="JobTitle" value="^[a-z A-Z&amp;)( \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,50}$" />
    <
    regexConfig name="Text" value="^[a-z A-Z \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,50}$" />
    <
    regexConfig name="Text100" value="^[a-z A-Z&amp;!. 0-9 \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,100}$" />
    <
    regexConfig name="Text1000" value="^[a-z A-Z&amp;!. 0-9 \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,1000}$" />
    <
    regexConfig name="AlphaNumeric" value="^[0-9a-z A-Z \xc0-\xd6 \xd8-\xf6 \xf9-\xff]+$" />
    <
    regexConfig name="BuildingName" value="^[0-9a-z A-Z' \xc0-\xd6 \xd8-\xf6 \xf9-\xff.,-]+[-]*[0-9a-z A-Z' \xc0-\xd6 \xd8-\xf6 \xf9-\xff.,-]*$" />
    <
    regexConfig name="Street" value="^[a-z A-Z' \xc0-\xd6 \xd8-\xf6 \xf9-\xff.,-]+$" />
    <
    regexConfig name="Address" value="^[a-z A-Z-' \xc0-\xd6 \xd8-\xf6 \xf9-\xff.]+$" />
    <
    regexConfig name="Postcode" value="(?i)^(((([A-PR-UWYZ][0-9][0-9]?)|(([A-PR-UWYZ][A-HK-Y][0-9][0-9]?)|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Z][0-9][ABEHMNPRVWXY]))))\s?[0-9][ABD-HJLNP-UW-Z]{2})|(GIR\s?0AA))$" />
    <
    regexConfig name="POBox" value="(?i)^((?!PO Box|POBox|P.O. Box|P.O.Box|P.O Box|PO. Box).)*$" />
    <
    regexConfig name="AccountNumber" value="^[0-9]{8}$" />
    <
    regexConfig name="EmployerName" value="^[0-9a-z A-Z\xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]+$" />
    <
    regexConfig name="SortCode" value="^[0-9]{2}$" />
    <
    regexConfig name="Income" value="^(0|[1-9]{1}(,[0-9]{3}){0,2}|[1-9]{1}[0-9]{0,2}(,[0-9]{3})?|[1-9]{1}[0-9]{0,6})$" />
    <
    regexConfig name="Expenditure" value="^([1-9]{1}(,[0-9]{3}){0,2}|[1-9]{1}[0-9]{0,2}(,[0-9]{3})?|[1-9]{1}[0-9]{0,6})$" />
    <
    regexConfig name="InternetID" value="^[a-z A-Z \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{6,13}$" />
    <
    regexConfig name="MemorableWord" value="^[a-zA-Z0-9'-]{6,20}$" />
    <
    regexConfig name="PIN" value="^[0-9]{5,5}$" />
    <
    regexConfig name="Decimal" value="^[0-9]+$" />
    <
    regexConfig name="DDMMYYYY" value="^((((0?[1-9]|[12]\d|3[01])(0?[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)(0?[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])0?2((1[6-9]|[2-9]\d)?\d{2}))|(290?2((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$"/>
    <
    regexConfig name="SubmissionName" value="^[a-z A-Z&amp;!)(# 0-9 \xc0-\xd6 \xd8-\xf6 \xf9-\xff'-]{2,100}$" />
    </
    regularExpressions>
    </
    regexSection>

    Sunday, February 8, 2009

    Query String Utilities

    Every time I write any web layer code, I always end up have to manipulate query strings and this little class pays dividends when manipulating the Query String

    Uri mainUrl = . . . 
    QueryStringCollection queryString = new QueryStringCollection(mainUrl.Query);
    queryString.Add("BookingEventId", bookingEventId.ToString());

    So here is the class, it has indexers, contains, to strings and will automatically Url encode.

    /// <summary>
    ///
    A chainable query string helper class.
    /// </summary>
    /// <example>
    ///
    string strQuery = QueryString.Current.Add("id", "179").ToString();
    /// string strQuery = new QueryString().Add("id", "179").ToString();
    /// </example>
    [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers",
    Justification="We are implementing a new object based collection."), Serializable]
    public class QueryStringCollection : NameValueCollection
    {
    public QueryStringCollection() { }

    /// <summary>
    ///
    Initializes a new instance of the <see cref="QueryStringCollection"/> class.
    /// </summary>
    /// <param name="info">
    A <see cref="T:System.Runtime.Serialization.SerializationInfo"/> object that contains the information required to serialize the new <see cref="T:System.Collections.Specialized.NameValueCollection"/> instance.</param>
    /// <param name="context">
    A <see cref="T:System.Runtime.Serialization.StreamingContext"/> object that contains the source and destination of the serialized stream associated with the new <see cref="T:System.Collections.Specialized.NameValueCollection"/> instance.</param>
    protected QueryStringCollection(SerializationInfo info, StreamingContext context)
    : base(info, context)
    {
    }

    /// <summary>
    ///
    Initializes a new instance of the <see cref="QueryStringCollection"/> class.
    /// </summary>
    /// <param name="queryString">
    The query string.</param>
    public QueryStringCollection(string queryString)
    {
    FillFromString(queryString);
    }

    /// <summary>
    ///
    Gets the current.
    /// </summary>
    /// <value>
    The current.</value>
    public static QueryStringCollection Current
    {
    get
    {
    return new QueryStringCollection().FromCurrent();
    }
    }

    /// <summary>
    ///
    Extracts the query string.
    /// </summary>
    /// <param name="value">
    The value.</param>
    /// <returns></returns>
    public static string ExtractQueryString(string value)
    {
    if (!string.IsNullOrEmpty(value))
    {
    if (value.Contains("?"))
    return value.Substring(value.IndexOf("?", StringComparison.OrdinalIgnoreCase) + 1);
    }
    return value;
    }

    /// <summary>
    ///
    Fills from string.
    /// </summary>
    /// <param name="value">
    The value.</param>
    /// <returns></returns>
    public QueryStringCollection FillFromString(string value)
    {
    base.Clear();
    if (string.IsNullOrEmpty(value)) return this;
    foreach (string keyValuePair in ExtractQueryString(value).Split('&'))
    {
    if (string.IsNullOrEmpty(keyValuePair)) continue;
    string[] split = keyValuePair.Split('=');
    base.Add(split[0],
    split.Length == 2 ? split[1] : "");
    }
    return this;
    }

    /// <summary>
    ///
    returns a QueryString object based on the current querystring of the request
    /// </summary>
    /// <returns>
    the QueryString object </returns>
    public QueryStringCollection FromCurrent()
    {
    if (HttpContext.Current != null)
    {
    return FillFromString(HttpContext.Current.Request.QueryString.ToString());
    }
    base.Clear();
    return this;
    }

    /// <summary>
    ///
    add a name value pair to the collection
    /// </summary>
    /// <param name="name">
    the name</param>
    /// <param name="value">
    the value associated to the name</param>
    /// <returns>
    the QueryString object </returns>
    public new QueryStringCollection Add(string name, string value)
    {
    return Add(name, value, false);
    }

    /// <summary>
    ///
    adds a name value pair to the collection
    /// </summary>
    /// <param name="name">
    the name</param>
    /// <param name="value">
    the value associated to the name</param>
    /// <param name="isUnique">
    true if the name is unique within the querystring. This allows us to override existing values</param>
    /// <returns>
    the QueryString object </returns>
    public QueryStringCollection Add(string name, string value, bool isUnique)
    {
    string existingValue = base[name];
    if (string.IsNullOrEmpty(existingValue))
    base.Add(name, HttpUtility.UrlEncodeUnicode(value));
    else if (isUnique)
    base[name] = HttpUtility.UrlEncodeUnicode(value);
    else
    base
    [name] += "," + HttpUtility.UrlEncodeUnicode(value);
    return this;
    }

    /// <summary>
    ///
    removes a name value pair from the querystring collection
    /// </summary>
    /// <param name="name">
    name of the querystring value to remove</param>
    /// <returns>
    the QueryString object</returns>
    public new QueryStringCollection Remove(string name)
    {
    string existingValue = base[name];
    if (!string.IsNullOrEmpty(existingValue))
    base.Remove(name);
    return this;
    }

    /// <summary>
    ///
    clears the collection
    /// </summary>
    /// <returns>
    the QueryString object </returns>
    public QueryStringCollection Reset()
    {
    base.Clear();
    return this;
    }

    /// <summary>
    ///
    Encrypts the keys and values of the entire querystring acc. to a key you specify
    /// </summary>
    /// <returns>
    an encrypted querystring object</returns>
    public QueryStringCollection Encrypt()
    {
    QueryStringCollection qs = new QueryStringCollection();
    for (var i = 0; i < base.Keys.Count; i++)
    {
    if (!string.IsNullOrEmpty(base.Keys[i]))
    {
    foreach (string val in base[base.Keys[i]].Split(','))
    qs.Add(base.Keys[i].Encrypt(), HttpUtility.UrlDecode(val).Encrypt());
    }
    }
    return qs;
    }

    /// <summary>
    ///
    Decrypts the keys and values of the entire querystring acc. to a key you specify
    /// </summary>
    /// <returns>
    a decrypted querystring object</returns>
    public QueryStringCollection Decrypt()
    {
    QueryStringCollection qs = new QueryStringCollection();
    for (var i = 0; i < base.Keys.Count; i++)
    {
    if (!string.IsNullOrEmpty(base.Keys[i]))
    {
    foreach (string val in base[base.Keys[i]].Split(','))
    qs.Add(HttpUtility.UrlDecode(base.Keys[i]).Decrypt(), HttpUtility.UrlDecode(val).Decrypt());
    }
    }
    return qs;
    }

    /// <summary>
    ///
    overrides the default
    /// </summary>
    /// <param name="name"></param>
    /// <returns>
    the associated decoded value for the specified name</returns>
    public new string this[string name]
    {
    get
    {
    return HttpUtility.UrlDecode(base[name]);
    }
    }

    /// <summary>
    ///
    overrides the default indexer
    /// </summary>
    /// <param name="index"></param>
    /// <returns>
    the associated decoded value for the specified index</returns>
    public new string this[int index]
    {
    get
    {
    return HttpUtility.UrlDecode(base[index]);
    }
    }

    /// <summary>
    ///
    checks if a name already exists within the query string collection
    /// </summary>
    /// <param name="name">
    the name to check</param>
    /// <returns>
    a boolean if the name exists</returns>
    public bool Contains(string name)
    {
    string existingValue = base[name];
    return !string.IsNullOrEmpty(existingValue);
    }

    /// <summary>
    ///
    outputs the querystring object to a string
    /// </summary>
    /// <returns>
    the encoded querystring as it would appear in a browser</returns>
    public override string ToString()
    {
    StringBuilder builder = new StringBuilder();
    for (var i = 0; i < base.Keys.Count; i++)
    {
    if (!string.IsNullOrEmpty(base.Keys[i]))
    {
    foreach (string val in base[base.Keys[i]].Split(','))
    builder.Append((builder.Length == 0) ? "?" : "&").Append(HttpUtility.UrlEncodeUnicode(base.Keys[i])).Append("=").Append(val);
    }
    }
    return builder.ToString();
    }
    }

    Guid.TryParse()

    Are you ever passed GUID’s via a query string? How can you trust that it is a real GUID? I want to be able to do this

    Guid result;
    if (GuidHelper.TryParse(Request["ID"], out result))
    return result;
    else
    return null
    ;


    I have to parse Guids occasionally so I wrote this little helper to add to where the .Net Framework is lacking.



    public static class GuidHelper
    {
    private static Regex guidFormat = new Regex(
    "^[A-Fa-f0-9]{32}$|" +
    "^({|\\()?[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}(}|\\))?$|" +
    "^({)?[0xA-Fa-f0-9]{3,10}(, {0,1}[0xA-Fa-f0-9]{3,6}){2}, {0,1}({)([0xA-Fa-f0-9]{3,4}, " +
    "{0,1}){7}[0xA-Fa-f0-9]{3,4}(}})$",
    RegexOptions.Compiled|RegexOptions.CultureInvariant|RegexOptions.Singleline);


    /// <summary>
    ///
    Converts the string representation of a Guid to its Guid
    /// equivalent. A return value indicates whether the operation
    /// succeeded.
    /// </summary>
    /// <param name="value">
    A string containing a Guid to convert.</param>
    /// <param name="result">
    ///
    When this method returns, contains the Guid value equivalent to
    /// the Guid contained in <paramref name="value"/>, if the conversion
    /// succeeded, or <see cref="Guid.Empty"/> if the conversion failed.
    /// The conversion fails if the <paramref name="value"/> parameter is a
    /// <see langword="null" /> reference (<see langword="Nothing" /> in
    /// Visual Basic), or is not of the correct format.
    /// </param>
    /// <value>
    /// <see langword="true" />
    if <paramref name="value"/> was converted
    /// successfully; otherwise, <see langword="false" />.
    /// </value>
    /// <exception cref="ArgumentNullException">
    ///
    Thrown if <pararef name="value"/> is <see langword="null"/>.
    /// </exception>
    public static bool TryParse(string value, out Guid result)
    {
    if (!string.IsNullOrEmpty(value))
    {
    Match match = guidFormat.Match(value);
    if (match.Success)
    {
    result = new Guid(value);
    return true;
    }
    }
    result = Guid.Empty;
    return false;
    }
    }

    Triple DES Encrypt/decrypt extension method

    I wanted to have a simple encryption method so that I could convert any string.
    return credentials.Encrypt();


    You should note that there is no constructor as it is better to initialise our key with a function call.


    /// <summary>
    ///
    The class will encrypt or decrpyt based on Triple DES algoritm
    /// </summary>
    public static class EncryptionService
    {
    static byte[] _encryptionKey = InitialiseKey();

    /// <summary>
    ///
    Initialises the key.
    /// </summary>
    /// <returns></returns>
    private static byte[] InitialiseKey()
    {
    string encryptionKey = ConfigurationManager.AppSettings["EncryptionPassword"];
    if (string.IsNullOrEmpty(encryptionKey))
    throw new ConfigurationErrorsException(
    "'EncryptionPassword' is not defined in your config file."
    );

    byte[] encryptionKeyBytes = ASCIIEncoding.ASCII.GetBytes(encryptionKey);

    using (MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider())
    {
    return hashmd5.ComputeHash(encryptionKeyBytes);
    }
    }

    /// <summary>
    ///
    Decrypts the specified input.
    /// </summary>
    /// <param name="input">
    The input.</param>
    /// <returns></returns>
    public static string Decrypt(this string input)
    {
    if (string.IsNullOrEmpty(input))
    return string.Empty;

    using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
    {
    des.Key = _encryptionKey;
    des.Mode = CipherMode.ECB;

    byte[] buff = null;
    try
    {
    buff = Convert.FromBase64String(input);
    }
    catch (FormatException)
    {
    return string.Empty;
    }

    return ASCIIEncoding.ASCII.GetString(
    des.CreateDecryptor().TransformFinalBlock(buff, 0, buff.Length));
    }
    }

    /// <summary>
    ///
    Encrypts the specified input.
    /// </summary>
    /// <param name="input">
    The input.</param>
    /// <returns></returns>
    public static string Encrypt(this string input)
    {
    using (TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider())
    {
    des.Key = _encryptionKey;
    des.Mode = CipherMode.ECB;

    byte[] buff = ASCIIEncoding.ASCII.GetBytes(input);

    return Convert.ToBase64String(
    des.CreateEncryptor().TransformFinalBlock(buff, 0, buff.Length));
    }
    }
    }

    Formatted Code in a blog

    I realised that over the years I have never blogged any of my work as I never had time. So now I intend to address this matter and place little utilities and snippets up for other people. First I wanted to make all of my code look nice and neat, so I started looking at the following blog.


    But then I found this little add-in