C# Null-Coalescing (??) operator
The null-coalescing operator (??) is one of my favorites, and I see so few developers using it.
MSDN defines the null-coalescing operator as
The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise it returns the right operand.
Although this is somewhat similar to a conditional operator (sometimes called 'ternary operator'), it is much more concise.
The null-coalescing operator works with nullable value types and reference types. When I first started with the null-coalescing operator, I often underestimated the usage with empty strings. I think this is very important to discuss, hence this blog post.
Strings
For example:
// conditional operator string example = null; string first = example == null ? "default" : example; // null-coalescing operator string second = example ?? "default";
In both of these cases, the resulting string will be "default".
The problem with strings is that the null-coalescing operator only checks against nulls. Code may often return String.Empty instead of nulls. Meaning the following example is not the same.
// conditional operator string example = string.Empty; string first = string.IsNullOrEmpty(example) ? "default" : example; // null-coalescing operator string second = example ?? "default";
In this example, 'first' will be "default" while 'second' will be the empty string. This is a situation in which the null-coalescing operator is useful only when a string must not be null but string.Empty is still perfectly valid.
Nullable Value Types
When working with nullable types, the conditional and null-coalescing operators have another alternative when retrieving the underlying value: GetValueOrDefault(). The problem here is that the method returns the value type, not another nullable type.
For example:
int? example = null; // Conditional operator int? first = example == null ? 100 : example; int firstValue = first.Value; // null-coalescing operator int? second = example ?? 100; int secondValue = second.Value; // GetValueOrDefault() int third = example.GetValueOrDefault(); // third = 0 int fourth = example.GetValueOrDefault(100); // fourth = 100
Notice the catch in the GetValueOrDefault() example... you don't have to reassign the nullable and then get the value. This is useful when you only need the value type. Sometimes, you need a default value and the nullable type. In these cases, I still prefer the null-coalescing operator.
Reference types
The null-coalescing operator can be used with reference types to guarantee that properties or methods do not return nulls.
For example:
public List<Person> People
{
get
{
return _people ?? new List<Person>();
}
set { /* something */ }
}
This is definitely a design/coding preference. I've experienced environments where developers insist on the importance of the NullReferenceException being thrown in production code. I've also experience plenty of environments where exceptional code is properly handled and this construct would rarely, if ever, be useful.
Maybe it is not a well-known operator, or most developers would like code to be lengthier and explicit. In a web development team, I think the null-coalescing operator is very similar to the common JavaScript example of providing a default value using the || operator:
var process = function(val) {
val = val || 100;
/* etc. */
}
Visual Studio and Interface property stubs
Last year, I posted a question on StackOverflow asking if it was possible to replace the property stubs for interface refactoring
Is it possible to change the stub used to implement interfaces in Visual Studio 2008?
For instance, when I choose either
Implement interface 'IMyInterface'
or
Explicitly implement interface 'IMyInterface'
Instead of a number of properties that look like this:
public string Comment
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
I'd like my properties to use the C# 3.0 auto-implemented properties and look like this:
public string Comment {get;set;}
I want to do this to avoid forcing this interface to be an abstract class.
I've looked through the snippets in the Visual Studio folder, but I didn't see any that would be appropriate. I've also googled and searched SO, and found nothing.
If this isn't possible, does anyone have a macro I can steal?
Thanks.
I then discovered that you can edit the file at:
[program files]\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Refactoring\PropertyStub.snippet
and modify the xml node 'Code' to contain the following:
<Code Language="csharp">
<![CDATA[ $signature$ { $GetterAccessibility$ get; $SetterAccessibility$ set;} $end$]]>
</Code>
I really wish this was the default for .NET 3.0 and higher (since auto-implemented properties have been around).
DataAnnotations, MVC 3, and Unobtrusive Validations
DataAnnotations are a pretty cool introduction to .NET 3.5+. It is very useful in ASP.NET MVC 3, and I've written a somewhat naive attempt to use this functionality in ASP.NET Web Forms which some people have found very useful.
I'd like to dig a little more in depth...
Bitwise Operations: Examples
One post that I've always loved on stackoverflow is this post by Hugoware which contains some useful extension methods for bitwise operations.
Bitwise operations can be used to perform all kinds of useful calculations. Below are some examples to whet your appetite for knowledge.
1) List of Integers trickery
You may have seen this question somewhere in some form or another: "Given a list of integers of unknown size where all but one integer occurs an even number of times, find the odd integer." This is usually a part of some algorithm coding-for-fun puzzle. When I first came across this question, I tried a number of different ways to loop through a list, none of which were optimal. In the end, I realized you can use XOR bitwise operations to do this.
First, create a list of integers and set your control integer to 23:
List<int> items = new List<int>();
for (int i = 0; i < 100; i++) {
items.Add(i);
if(i == 23) { items.Add(i); }
}
Then, create a value to keep watch, and perform an XOR on every value:
int found = 0;
foreach (int item in items) {
found ^= item;
}
Finally, output to console or inspect the found variable to be sure it contains the number 23.
Why this works
The complexity of this algorithm is O(n)--one operation per n items. It doesn't get any easier than that. If you were to add more loops or extra data structures to maintain values, you degrade performance.
If you've read my previous post about bitwise operations, you may remember that an XOR toggles the bits. When you start at zero, all even occurrences will be zero when the loop is completed. The only bits left will be the bits from the odd occurrence of an integer (in other words, 0 ^ 23 = 23).
Cool, huh?
2) Division by 2 or 3
This is one of the few things I remember from my Information Systems class at VCU (sorry, Dr. Wynne). My professor work on a project many years ago, trying to debug a performance issue. When running through certain calculations, the application performance would reduce by orders of magnitude. The problem was with how the application was performing division. Sorry, I don't remember the exact details because I think it was being done in Assembly (I guess I don't even remember this story from VCU!). The solution was to perform bitwise division on the value. For example:
List<int> items = new List<int>();
for (int i = 0; i < 1000; i+=2) {
items.Add(i);
}
foreach (int item in items) {
Console.WriteLine("{0} / 2 = {1}", item, item >> 1);
}
Why this works
Let's look at a single number, 6. The bits for 6 look like:
0 1 1 0
This means the 2 bit and the 4 bit are set. If you use the right-shift operator ('>>'), you're moving all of the bits that many positions to the right. So, if you perform '6 >> 1', you get:
0 0 1 1
Sure enough, that's 3!
Now, you may be thinking "How often do I need to divide by 2?" Well, this doesn't just work for the number 2. You can lop off any number of bits.
x >> 2 is the same as x / 4 ( or x / (2^2) ).
x >> 3 is the same as x / 8 ( or x / (2^3) ).
And so on...
What if I want to divide by an odd number?!
Then do something like: x / 3. Seriously. If you're interested, you can take a look at this post on stackoverflow.
What you do in this case is use a magic number which causes the left-most 32bits in a 64bit result to be equal to the result of dividing by 3. Then you shift those 32 insignificant bits off. Be careful, though, because you can easily overflow your value type. Here's an example:
Console.WriteLine("300 / 3 = {0}", (300L * 1431655766) >> 32 );
If you look at the binary for that magic number (1431655766), you'll see:
0101 0101 0101 0101 0101 0101 0101 0110
You don't need to memorize this magic number. You can easily build it:
int result = 0;
for(int i = 1; i<=8; i++) {
result = (result << 4) ^ 5;
}
result += 1;
This takes the binary representation of 5 (0101) and buffers that nibble until it fills 32 bits, then adds 1 which basically moves the last bit. That's the magic. We've created a magic number which is 6 (110) preceded by alternating 1's and 0's.
To see what this is doing in something a little simpler like 6/3=2, you can run this bit of code and inspect the binary displayed.
long tester = 6L * 1431655766; Console.WriteLine(Convert.ToString(tester, 2).PadLeft(36, '0'));
Notice that I used 36 digits to pad because I know 6/3 is 2 and I only need 4 extra bits to show that. In the binary below, instead of separating each by by a space, I've separated the 32 bits we'll lop off from the end result.
0010 00000000000000000000000000000100
When you shift this result by 32 bits, you're left with the answer: 2.
Why does this work?
Take, for example, the magic number multiplied by 243 = 347892351138.
Our answer should be: 243/3 = 81.
01010101010101010101010101010110
x 11110011
______________________________________________
01010101010101010101010101010110
0 10101010101010101010101010101100
00 00000000000000000000000000000000
000 00000000000000000000000000000000
0101 01010101010101010101010101100000
01010 10101010101010101010101011000000
010101 01010101010101010101010110000000
0101010 10101010101010101010101100000000
______________________________________________
1010001 00000000000000000000000010100010
As you can see, the end result (the last line) is the binary representation of 81!
3) Obfuscation
You can use XOR or any other bitwise operation to obfuscate a string. The idea is to take a single character, XOR all characters in a sentence with your secret to obfuscate. To deobfuscate, you XOR all characters in your obfuscated string and the result should be your original string!
Here's a quick example:
char key = '*';
string sentence = "Would you like to play a game?!";
Console.WriteLine("Original string: '{0}'", sentence);
string obfuscated = String.Empty;
foreach (var item in sentence) {
obfuscated += (char)(item ^ key);
}
Console.WriteLine("obfuscated string: {0}", obfuscated);
string deobfuscated = String.Empty;
foreach (var item in obfuscated) {
deobfuscated += (char)(item ^ key);
}
Console.WriteLine("deobfuscated string: {0}", deobfuscated);
The output should look something like (non-printing characters are not displayed, so you may see something slightly different):
Original string: 'Would you like to play a game?!' obfuscated string: }E_FN SE_ FCAO ^E ZFKS K MKGO deobfuscated string: Would you like to play a game?!
Bitwise operations and Flags (C#)
I haven't written anything in a while, so I thought I would finally write about the subject of bitwise operations and the FlagsAttribute.
I mentioned this to one of the developers on my team, and he said that he somewhat understood bit operations but he had never found a reason to use them.
Here is the code I will use to discuss the operations
int a = 57754;
int b = 18782;
int aXORb = a ^ b;
int aORb = a | b;
int aANDb = a & b;
int aNOT = ~a;
int bNOT = ~b;
string spacer = "---------------------------------------------";
Console.WriteLine("{0} ({1}) a", GetBitString(a), a.ToString());
Console.WriteLine("{0} ({1}) b", GetBitString(b), b.ToString());
Console.WriteLine("{0} ({1}) a ^ b", GetBitString(aXORb), aXORb);
Console.WriteLine(spacer);
Console.WriteLine("{0} ({1}) a", GetBitString(a), a.ToString());
Console.WriteLine("{0} ({1}) b", GetBitString(b), b.ToString());
Console.WriteLine("{0} ({1}) a | b", GetBitString(aORb), aORb);
Console.WriteLine(spacer);
Console.WriteLine("{0} ({1}) a", GetBitString(a), a.ToString());
Console.WriteLine("{0} ({1}) b", GetBitString(b), b.ToString());
Console.WriteLine("{0} ({1}) a & b", GetBitString(aANDb), aANDb);
Console.WriteLine(spacer);
Console.WriteLine("{0} ({1}) a", GetBitString(a), a.ToString());
Console.WriteLine("{0} ({1}) ~a", GetBitString(aNOT), aNOT);
Console.WriteLine("{0} ({1}) ~(~a)", GetBitString(~aNOT), ~aNOT);
Console.WriteLine(spacer);
Console.WriteLine("{0} ({1}) b", GetBitString(b), b.ToString());
Console.WriteLine("{0} ({1}) ~b", GetBitString(bNOT), bNOT);
Console.WriteLine("{0} ({1}) ~(~b)", GetBitString(~bNOT), ~bNOT);
Console.ReadLine();
// And, the GetBitString method
static string GetBitString(int input){
int sizeInt;
// Number of bits is bytes * 8
// I specifically chose 16-bit values to reduce the amount displayed
unsafe{ sizeInt = (sizeof(ushort) * 8); }
string output = String.Empty;
for (; sizeInt >= 0; sizeInt--) {
output += (input >> sizeInt) & 1;
if(sizeInt % 4 == 0) { output += " "; }
}
return output;
}
XOR ( ^ )
From MSDN:
Binary ^ operators are predefined for the integral types and bool. For integral types, ^ computes the bitwise exclusive-OR of its operands. For bool operands, ^ computes the logical exclusive-or of its operands; that is, the result is true if and only if exactly one of its operands is true.
I think of XOR as a "one-toggle". The logic can be seen as (format is [first] : [second] --> [result] ):
0 : 1 --> 1 1 : 1 --> 0 1 : 0 --> 1 0 : 0 --> 0
As you can see,
Learning WCF: IIS 7 won’t start service from web project
I'm following along with code in Learning WCF, attempting to quickly become an expert at building WCF Services from scratch. In Chapter 1, there is a project called IISHostedService. After making the quick modifications to the downloaded code, and running the application, IIS 7.0 (Windows 7, 64bit) doesn't serve the services, complaining about adding a MIME type. I thought this was rather fishy, because I've created WCF Services while in school under Windows XP and they ran fine.
It turns out that I didn't have WCF properly setup. To do so, you have to run
C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\servicemodelreg -i
This will provide the following output (which is everything I was missing):
Microsoft(R) Windows Communication Foundation Installation Utility [Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.4926] Copyright (c) Microsoft Corporation. All rights reserved. Installing: Machine.config Section Groups and Handlers (WOW64) Installing: Machine.config Section Groups and Handlers Installing: System.Web Build Provider (WOW64) Installing: System.Web Compilation Assemblies (WOW64) Installing: HTTP Handlers (WOW64) Installing: HTTP Modules (WOW64) Installing: System.Web Build Provider Installing: System.Web Compilation Assemblies Installing: HTTP Handlers Installing: HTTP Modules Installing: Protocol node for protocol net.tcp (WOW64) Installing: TransportConfiguration node for protocol net.tcp (WOW64) Installing: ListenerAdapter node for protocol net.tcp Installing: Protocol node for protocol net.tcp Installing: TransportConfiguration node for protocol net.tcp Installing: Protocol node for protocol net.pipe (WOW64) Installing: TransportConfiguration node for protocol net.pipe (WOW64) Installing: ListenerAdapter node for protocol net.pipe Installing: Protocol node for protocol net.pipe Installing: TransportConfiguration node for protocol net.pipe Installing: Protocol node for protocol net.msmq (WOW64) Installing: TransportConfiguration node for protocol net.msmq (WOW64) Installing: ListenerAdapter node for protocol net.msmq Installing: Protocol node for protocol net.msmq Installing: TransportConfiguration node for protocol net.msmq Installing: Protocol node for protocol msmq.formatname (WOW64) Installing: TransportConfiguration node for protocol msmq.formatname (WOW64) Installing: ListenerAdapter node for protocol msmq.formatname Installing: Protocol node for protocol msmq.formatname Installing: TransportConfiguration node for protocol msmq.formatname Installing: HTTP Modules (WAS) Installing: HTTP Handlers (WAS)
Using DataAnnotation attributes to validate Membership password
As a follow-up to my post on DataAnnotations in ASP.NET Web Forms, I'd like to demonstrate yet another custom attribute. Although ASP.NET offers a CreateUserWizard, if your custom membership provider is way more complicated, you will probably be better off creating a control from scratch. If you go this route, you'll have to provide some of the functionality from the CreateUserWizard. Here is a simple attribute which checks *only* password complexity and builds an ErrorMessage without ever calling the CreateUser method.
This attribute can be added to a password property and validate against the *Default* Membership Provider.
Here is the code:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class MembershipPasswordRequiredAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
if (value == null || !(value is string) || string.IsNullOrEmpty(value.ToString()))
{
return false;
}
MembershipSection membershipConfig = (MembershipSection)WebConfigurationManager
.GetSection("system.web/membership");
var providerSettings = membershipConfig.Providers[membershipConfig.DefaultProvider];
string minLength = providerSettings.Parameters["minRequiredPasswordLength"];
string minAlpha = providerSettings.Parameters["minRequiredNonalphanumericCharacters"];
if (string.IsNullOrEmpty(this.ErrorMessage) && !string.IsNullOrEmpty(minLength))
{
string message = String.Empty;
message = String.Format("Password must be at least {0} characters in length", minLength);
if (!string.IsNullOrEmpty(minAlpha))
{
message = String.Format("{0} and contain at least {1} special character", message, minAlpha);
}
this.ErrorMessage = message;
}
/* Validate against your provider and return true or false */
}
}
Usage:
[MembershipPasswordRequired]
internal string Password {get;set;}
The cool thing about this attribute is that you can decorate a property without specifying the ErrorMessage and it will build one dynamically from your default membership. Of course, you can change this up if you're using multiple providers by getting the key of the current provider. But, the project I'm working on will always only have one provider, so this is how I'll leave it.
A caveat: You can only set the ErrorMessage property once. If you try to assign to it more than once, you will receive an exception telling you this.
I won't post the code for validating against the provider, because there are a number of ways to do this. Probably the safest way to do so is to use regex validation and pull that property from the provider's parameters and just return whether the regex matches the string or not.
Anyway, I thought this was a pretty cool usage of DataAnnotations, and hooking it up on a custom CreateUser control was trivial with the DataAnnotation validator (from a few posts ago).
System.ComponentModel.DataAnnotations for ASP.NET Web Forms
Although I'm primarily an ASP.NET Web Forms developer, I regularly dabble in new and interesting technologies. I've toyed with other Microsoft technologies such as ASP.NET MVC and Dynamic Data web sites.
ASP.NET MVC offers an interesting mechanism for validating view models called DataAnnotations. Examples can be seen here and here.
Some of the more useful attributes for validation include:
- RequiredAttribute
- RegularExpressionAttribute
- RangeAttribute
- DataTypeAttribute
I recently decided to implement a data validation schema (for lack of a better term) for web forms similar to that of ASP.NET MVC. This would allow us to maintain validation of a model object via attributes at the class level, instead of dispersing these validation rules through the web form code or any of the business logic layers. However, there will be occasions where an object's validity depends upon some state or validity of another object. I've handled this by allowing the validation method to accept any action to be called after the object has been validated.
In order to make a domain object validatable, I'm going to implement the following interface:
IValidatable.cs
namespace Validatable
{
interface IValidatable
{
System.Type EntityType { get; set; }
System.Collections.Generic.List<object> Errors { get; set; }
/// <summary>
/// Determine whether the object is valid. If invalid, errors are added to item.Errors
/// </summary>
/// <returns>true if valid, false if invalid</returns>
bool IsValid();
/// <summary>
/// Validate this item against a supplied action
/// </summary>
/// <param name="action">The action to use for validation</param>
void Validate(System.Action action);
/// <summary>
/// Validate this object against a Repository.
/// <example>
/// Item a = new Item();
/// a.Validate(new ItemRepository());
/// </example>
/// Note: Repository must have a Validate(T item) method
/// </summary>
/// <param name="repository">The Repository to use for validation</param>
void Validate(object repository);
}
}
As you can see, this abstract class adds a property accessor for the entity's type, a list of validation errors, an IsValid method, and two Validate methods.
Validatable<T>
I'll take the code in chunks, since there is a lot more than I usually post.
First of all, the using directives required for this class are pretty sparse:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
The class definition is:
[Serializable]
public abstract class Validatable<T> : IValidatable where T : class, new()
{ /* class */ }
If you're unfamiliar with generic constraints, the where T : class, new() above enforces the T passed as in to be a class and to have a parameterless constructor (new())
The properties can be auto-implemented properties, or they can implement any backing logic you prefer. The constructor as I have it is:
protected Validatable()
{
Errors = new List<object>();
EntityType = typeof(T);
}
Now for the methods and a slight explanation of each:
IsValid()
public virtual bool IsValid()
{
Errors = new List<object>();
PropertyInfo[] props = this.GetType().GetProperties();
foreach (PropertyInfo property in props)
{
foreach (ValidationAttribute va in
property.GetCustomAttributes(true).OfType<ValidationAttribute>())
{
var value = property.GetValue(this, null);
if (!va.IsValid(value))
{
Errors.Add(va.ErrorMessage);
}
}
}
return Errors.Count <= 0;
}
As a side note, all DataAnnotation attributes inherit from ValidationAttribute. You can create your own Validation Attributes by inheriting from this class. This method clears the list of errors and repopulates it by looping over any properties with validation attributes of this object, validates that property's value against the attribute, and adds the ErrorMessage associated with it to the list of Errors.
Validate Methods
public virtual void Validate(Action action)
{
if (IsValid())
{
action();
}
}
public virtual void Validate(object repository)
{
MethodInfo method = repository.GetType().GetMethods()
.Where(x => x.Name.Equals("Validate")).FirstOrDefault();
if (method != null)
{
object[] parameters = new object[] { this };
Validate(() => method.Invoke(repository, parameters));
}
}
These two methods can be changed to throw an exception if the object is invalid. I'll leave that up to you. The way these are set up is to allow you to validate the object and perform either some unknown action or call Validate(T item) against some other object, arbitrarily called a repository. In actuality, you could have a Validate method on some other object that takes an object of this type and essentially chain validations.
The simplicity of the Validate(Action action) method is what makes it beautiful. For instance, you can have an item (a) and cause it save after validation by doing something like:
a.Validate(() => new ItemDAL().Save(a));
As you can see, a Save method in your Item's Data Access Layer taking Item as a parameter can be called only when a.IsValid() is true. Again, there are a number of ways to tweak this and change it to your liking, but I'll leave that up to you.
DataAnnotationValidator
Here is the wonderful part about all of this. You can create a custom validator that validates in a similar way as the Validatable class. I'll post the code and quickly explain what it does. I got the idea from this from another blog and tweaked it a little.
DataAnnotationValidator.cs
// DataAnnotationValidator.cs
namespace Validatable
{
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
[ToolboxData("<{0}:DataAnnotationValidator runat=\"server\" ControlToValidate=\"[Required]\" Display=\"Dynamic\" Text=\"*\" SourceTypeName=\"[FullyQualifiedTypeName]\" PropertyToValidate=\"[PropertyName]\" />")]
public class DataAnnotationValidator : BaseValidator
{
/// <summary>
/// THe Property that should be checked
/// </summary>
public string PropertyToValidate { get; set; }
/// <summary>
/// The object's type
/// </summary>
public string SourceTypeName { get; set; }
protected override bool EvaluateIsValid()
{
Type source = GetValidatedType();
PropertyInfo property = GetValidatedProperty(source);
string value = GetControlValidationValue(ControlToValidate);
foreach (ValidationAttribute va in property
.GetCustomAttributes(typeof(ValidationAttribute), true)
.OfType<ValidationAttribute>())
{
if (!va.IsValid(value))
{
if (string.IsNullOrEmpty(ErrorMessage))
{
this.ErrorMessage = va.ErrorMessage;
}
return false;
}
}
return true;
}
private Type GetValidatedType()
{
if (string.IsNullOrEmpty(SourceTypeName))
{
throw new InvalidOperationException("Null SourceTypeName can't be validated");
}
Type validatedType = Type.GetType(SourceTypeName);
if (validatedType == null)
{
throw new InvalidOperationException(
string.Format("{0}:{1}", "Invalid SourceTypeName", SourceTypeName));
}
return validatedType;
}
private PropertyInfo GetValidatedProperty(Type source)
{
PropertyInfo property = source.GetProperty(PropertyToValidate,
BindingFlags.Public | BindingFlags.Instance);
if (property == null)
{
throw new InvalidOperationException(
string.Format("{0}:{1}", "Validated Property Does Not Exists", PropertyToValidate));
}
return property;
}
}
}
This creates a validator web control which has 'PropertyToValidate' and 'SourceTypeName'. When a Validator web control is added to a page, it must have ControlToValidate, PropertyToValidate, and SourceTypeName specified or an error will be thrown. The validation method verifies the type and the property, gets the value of the property and finally, much like the Validatable abstract class, it loops over all ValidationAttributes and validates the value against that attribute. You can use this with multiple attributes, so it doesn't hurt to add this validator to a property-- that just means you can add an attribute in the future and everything is already wired up! That's pretty cool.
Example
As an example, I'm going to create a single page to **input** a Customer object. The customer object is very simple:
public class Customer : Validatable.Validatable<Customer>
{
[Required(ErrorMessage="UserId is Required")]
public int UserId { get; set; }
[DataType(DataType.PhoneNumber, ErrorMessage="Invalid Phone Number")]
public string PhoneNumber { get; set; }
[RegularExpression(@"(^\d{5}(-\d{4}){0,1}$)", ErrorMessage="Invalid Zip Code")]
public string ZipCode { get; set; }
}
And the Page in full is collapsed below:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Example._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:Label ID="lblStatus" runat="server" />
<asp:ValidationSummary ID="ValidationSummary1" runat="server" />
<div>
<asp:FormView ID="FormView1" runat="server" DataSourceID="srcRepository"
Width="119px" AllowPaging="True">
<EditItemTemplate>
UserId:
<asp:TextBox ID="UserIdTextBox" runat="server" Text='<%# Bind("UserId") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator1" runat="server" ControlToValidate="UserIdTextBox" Display="Dynamic"
PropertyToValidate="UserId" ErrorMessage="Invalid User Identification Number"
SourceTypeName="Example.Customer, Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
Text="*"/>
<br />
PhoneNumber:
<asp:TextBox ID="PhoneNumberTextBox" runat="server"
Text='<%# Bind("PhoneNumber") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator2" runat="server" ControlToValidate="PhoneNumberTextBox" Display="Dynamic"
PropertyToValidate="PhoneNumber" OnInit="GetTypeName" SourceTypeName="Example.Customer, Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Text="*"/>
<br />
ZipCode:
<asp:TextBox ID="ZipCodeTextBox" runat="server" Text='<%# Bind("ZipCode") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator3" runat="server" ControlToValidate="ZipCodeTextBox" Display="Dynamic"
PropertyToValidate="ZipCode" SourceTypeName="Example.Customer, Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" Text="*"/>
<br />
EntityType:
<asp:TextBox ID="EntityTypeTextBox" runat="server"
Text='<%# Eval("EntityType") %>' />
<br />
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" />
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
<InsertItemTemplate>
UserId:
<asp:TextBox ID="UserIdTextBox" runat="server" Text='<%# Bind("UserId") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator1" runat="server" ControlToValidate="UserIdTextBox" Display="Dynamic"
PropertyToValidate="UserId" OnInit="GetTypeName" Text="*"/>
<br />
PhoneNumber:
<asp:TextBox ID="PhoneNumberTextBox" runat="server"
Text='<%# Bind("PhoneNumber") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator2" runat="server" ControlToValidate="PhoneNumberTextBox" Display="Dynamic"
PropertyToValidate="PhoneNumber" OnInit="GetTypeName" Text="*"/>
<br />
ZipCode:
<asp:TextBox ID="ZipCodeTextBox" runat="server" Text='<%# Bind("ZipCode") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator3" runat="server" ControlToValidate="ZipCodeTextBox" Display="Dynamic"
PropertyToValidate="ZipCode" OnInit="GetTypeName" Text="*"/>
<br />
EntityType:
<asp:TextBox ID="EntityTypeTextBox" runat="server"
Text='<%# Eval("EntityType") %>' />
<br />
<asp:LinkButton ID="InsertButton" runat="server" CausesValidation="True"
CommandName="Insert" Text="Insert" />
<asp:LinkButton ID="InsertCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel" Text="Cancel" />
</InsertItemTemplate>
<ItemTemplate>
UserId:
<asp:Label ID="UserIdTextBox" runat="server" Text='<%# Bind("UserId") %>' />
<br />
PhoneNumber:
<asp:Label ID="PhoneNumberTextBox" runat="server"
Text='<%# Bind("PhoneNumber") %>' />
<br />
ZipCode:
<asp:Label ID="ZipCodeTextBox" runat="server" Text='<%# Bind("ZipCode") %>' />
<br />
EntityType:
<asp:Label ID="EntityTypeLabel" runat="server"
Text='<%# Bind("EntityType") %>' />
<br />
<asp:LinkButton ID="EditButton" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit" />
<asp:LinkButton ID="NewButton" runat="server" CausesValidation="False"
CommandName="New" Text="New" />
</ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="srcRepository" runat="server"
DataObjectTypeName="Example.Customer" InsertMethod="Save"
oninserted="srcRepository_Saved" onupdated="srcRepository_Saved"
SelectMethod="Get" TypeName="Example.CustomerRepository" UpdateMethod="Save"></asp:ObjectDataSource>
</div>
</form>
</body>
</html>
Of particular note here is in the EditTemplate, you'll see
UserId:
<asp:TextBox ID="UserIdTextBox" runat="server" Text='<%# Bind("UserId") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator1" runat="server" ControlToValidate="UserIdTextBox" Display="Dynamic"
PropertyToValidate="UserId" ErrorMessage="Invalid User Identification Number"
SourceTypeName="Example.Customer, Example, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
Text="*"/>
in which the SourceTypeName must be the full Assembly Qualified Name. This is necessary if the Validatable
UserId:
<asp:TextBox ID="UserIdTextBox" runat="server" Text='<%# Bind("UserId") %>' />
<example:DataAnnotationValidator ID="DataAnnotationValidator1" runat="server" ControlToValidate="UserIdTextBox" Display="Dynamic"
PropertyToValidate="UserId" OnInit="GetTypeName" Text="*"/>
and the code in the code behind is very simple:
protected void GetTypeName(object sender, EventArgs e)
{
DataAnnotationValidator validator = (DataAnnotationValidator)sender;
validator.SourceTypeName = new Customer().EntityType.AssemblyQualifiedName;
}
Also notice that the first validator (the one with the assembly qualified name) has an ErrorMessage property specified. Doing this allows you to override the error message returned from the validated object. We can do this if the model says "UserId" and you want the user to see this property referred to as "User Identification".
Conclusion
Sometimes dabbling in other technologies can open the door for new and simpler ways of doing things. I like this example because it allows you to build web applications quickly and easily, while making them maintainable in the future (new validations only have to be added to the model, not to every control where the model must be validated).
For further reference, this project is linked below. Please download and modify if necessary.
Validatable.zip
Finding a user’s local time from UTC offset
I answered a question over at StackOverflow, and I really liked the answer, so I thought I would share this nifty extension method:
/// <summary>
/// Convert a given DateTime object to a user's local time,
/// taking into account changes in TimeZone rules.
/// For example, if you were to perform this operation on
/// a time now, during EST Daylight Saving, and that time falls
/// outside the scope of Daylight Saving time, the rule will adjust accordingly.
/// </summary>
/// <param name="dateTime">The DateTime object</param>
/// <param name="offset">offset from UTC</param>
/// <returns>User's local time</returns>
public static DateTime ConvertToLocalDateTime(this DateTime dateTime, int offset)
{
TimeZoneInfo destinationTimeZone = TimeZoneInfo.GetSystemTimeZones()
.Where(x => x.BaseUtcOffset.Hours.Equals(offset)).FirstOrDefault();
var rule = destinationTimeZone.GetAdjustmentRules().Where(x =>
x.DateStart <= dateTime && dateTime <= x.DateEnd)
.FirstOrDefault();
TimeSpan baseOffset = TimeSpan.Zero;
if (rule != null)
{
baseOffset -= destinationTimeZone.IsDaylightSavingTime(dateTime) ?
rule.DaylightDelta : TimeSpan.Zero;
}
DateTimeOffset dto = DateTimeOffset.Parse(dateTime.ToString());
return new DateTime(TimeZoneInfo
.ConvertTimeFromUtc(dateTime,
destinationTimeZone).Ticks + baseOffset.Ticks);
}
The summary basically says it all. I ran through a couple of tests with this, I'd like to know if anyone uses this and makes modifications to it!
NHibernate.Criterion Extensions workaround
I've been working with Fluent NHibernate for the past month or so, and I realized while writing an NHibernate query that the NHibernate Criterion's Restrictions class isn't very refactor-friendly. The refactorability of Fluent NHibernate is ultimately why we've decided to use it. It does take a little longer to set up than some other ORMs, but in the long-run it's nice to be able to change a property name and refactor.
... except the property names are hard-coded in the Criteria!
My workaround for this is to use a bit of static reflection a-la-FNH, and maintain code that is easily refactored.
For instance, I've created a static utility class (Showing the Restrictions.Eq() substitute):
public static class CriterionExtensions
{
public static SimpleExpression Eq<T>(
Expression<Func<T, object>> exp, object value
)
{
var memberExpression = GetMemberExpression(exp);
string propertyName = ((PropertyInfo)memberExpression.Member).Name;
if (!string.IsNullOrEmpty(propertyName))
return Restrictions.Eq(propertyName, value);
else
return null;
}
private static MemberExpression GetMemberExpression<T>(
Expression<Func<T, object>> expression
)
{
MemberExpression memberExpression = null;
if (expression.Body.NodeType == ExpressionType.Convert)
{
var body = (UnaryExpression)expression.Body;
memberExpression = body.Operand as MemberExpression;
}
else if (expression.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpression = expression.Body as MemberExpression;
}
if (memberExpression == null)
{
throw new ArgumentException("Not a member access", "member");
}
return memberExpression;
}
}
And to use this code, you can create an aliased using directive and call it in code:
using Ensure = MyNamespace.Extensions.Criterion.CriterionExtensions;
/* class declarations and whatnot */
internal IEnumerable<Product> GetAll(int shelfNumber)
{
var session = SessionManager.GetCurrentSession();
return session.CreateCriteria<Product>()
.Add(Ensure.Eq<Product>(x => x.ShelfNumber, shelfNumber))
.List<Product>();
}
It's pretty simple to use and is easily refactored. You may be able to add your *extensions* to a namespace: NHibernate.Criterion and call your class Restrictions, but I didn't try this (I don't like mixing namespaces). Let me know what you think!
