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 & 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

Tuesday, November 4, 2008

Using dictionaries for constant Identifiers

I wanted to have a constant string so that I could have a list of roles, however I also wanted to have a friendly description, so how do you go about this? The reason for using a constant string is so that we are consistent when we are checking our roles. e.g.
if (_user.IsInRole(Role.Practitioner))
{
. . .
}

But what happens when you want to get a friendly description too? Well firstly I wanted to be able to put all the roles I had defined into a drop down list, so it would be nice if all the roles were defined in one place. So I wanted to be able to do this

// Put the roles in the role dropdownlist
RoleDropDownList.DataSource = Role.Roles;
RoleDropDownList.DataTextField = "Value";
RoleDropDownList.DataValueField = "Key";
RoleDropDownList.DataBind();
RoleDropDownList.Items.Insert(0, new ListItem("All", ""));

So how do we do it? Simply use a dictionary. Have the key be the constant string and the value a friendly description. Now the important point to note here is that we could be tempted to use StringDictionary as it is a specialization of a Dictionary, but if you look carefully in the documentation, the key will be converted to a lower case string and that *is not what we want*.

/// <summary>
///
These are the membership roles that users can have
/// </summary>
public static class Role
{
/// <summary>A basic user (frozen user)</summary>
public const string Basic = "Basic";

/// <summary>A standard practitioner</summary>
public const string Practitioner = "Practitioner";

/// <summary>An IP administrator</summary>
public const string Administrator = "Administrator";

/// <summary>A training manager</summary>
public const string TrainingManager = "TrainingManager";

/// <summary>A submissions manager</summary>
public const string SubmissionManager = "SubmissionManager";

/// <summary>A submission assessor</summary>
public const string Assessor = "Assessor";

public const string Mentor = "Mentor";

/// <summary>
///
Create a friendly description of each role
/// </summary>
public static Dictionary<String, String> Roles
= new Dictionary<String, String>()
{
{ Basic, "Frozen User" },
{ Practitioner, "Practitioner" },
{ Administrator, "Administrator" },
{ TrainingManager, "Training Manager" },
{ SubmissionManager, "Submission Manager" },
{ Assessor, "Assessor"},
{ Mentor, "Mentor"}
};
}