This morning @JeffHandley tweeted this http://www.forkcan.com/viewcode/277/Null-Dot-Operator-Extension-Method essentially the idea is that you can call your code and apply default options. I kinda like the idea, but I wasn’t so convinced of the name he chose for the name of his extension method _ it kinda looks like an operator, but really isn’t and you have to start feeling for the guy reading your code 2 years after you left the company on this one.

Also, to use his code on nested properties you have to make a call like this:

var result = bar._(b => b.ChildProperty)._(c => c.StringProperty)

Which I’m not sure is exactly attractive to the eye. Also, if you did try to chain a whole bunch of properties together it might end up really, really hard to read.

Now, it’s easy to sit and snipe, but that’s crappy, so my implementation of his idea gets called like this:

var result = root.NeverNull((me) => me.SomeProperty.AnotherProperty.SomeProperty, defaultValue: new MyClass(3));

It’s not exactly beautiful, but I think it’s slightly more obvious. My implementation currently has the restriction that it only works for properties, not for methods. Anyway, the implementation is as follows, what do you think?

public static class CodeInsipredByJeff
{
    public static T NeverNull<T>(this object target, Expression<Func<T, T>> propertyExpression, T defaultValue) where T : class
    {
        var properties = GetProperties(GetExpression(propertyExpression));

        object currentTarget = target;
        foreach (var property in properties)
        {
            if (currentTarget == null)
            {
                return defaultValue;
            }
            currentTarget = property.GetValue(currentTarget, null);
        }

        if (currentTarget != null && currentTarget is T)
        {
            return (T)currentTarget;
        }
        else
        {
            return defaultValue;
        }
    }

    private static MemberExpression GetExpression<T>(Expression<Func<T>> expression)
    {
        var body = expression.Body;
        if (body is MemberExpression)
        {
            return body as MemberExpression;
        }
        else if (body is UnaryExpression)
        {
            var ue = body as UnaryExpression;
            return ue.Operand as MemberExpression;
        }
        else
        {
            throw new NotImplementedException();
        }
    }

    private static IEnumerable<PropertyInfo>GetProperties(Expression expression)
    {
        var memberExpression = expression as MemberExpression;
        if (memberExpression == null) yield break;

        var property = memberExpression.Member as PropertyInfo;
        if (property == null)
        {
            throw new NotSupportedException("Expression is not a property accessor");
        }
        foreach (var propertyInfo in GetProperties(memberExpression.Expression))
        {
            yield return propertyInfo;
        }
        yield return property;
    }
}

I’m not a big fan of using session, but sometimes there isn’t a sensible alternative. In that case I always wrap the session object in a property. In the past I’ve failed to come up with a satisfactory session variable naming convention. With that I’ve always hated using strings for session names. Each solution basically boils down to typing some strings some where in your code, either directly into the call to Session[] or the same process, but via a series of predefined const strings. Using a const string gets you slightly cleaner code, but there is nothing to prevent a developer picking the wrong const and ending up in a delightful mess.

Once you’ve got past the string mess, you then end up having to write code to check the session value, set a default value and return. Sure, it’s not hard, but you will end up writing a lot of repetitive code. That’s boring, laborious and error prone.

To try and fix both the string problem and to try and keep my code nice and D.R.Y I’ve come up with is this:

    public class SessionManager: ISessionManager
    {
        private HttpSessionState Session
        {
            get { return HttpContext.Current.Session; }
        }

        public T GetSessionValue(Expression<Func<T>> expression, T defaultValue)
        {
            var sessionKey = GetSessionKey(expression);
            object sessionValue = Session[sessionKey];
            if (sessionValue == null || ! typeof(T).IsAssignableFrom(sessionValue.GetType()))
            {
                Session[sessionKey] = defaultValue;
                sessionValue = defaultValue;
            }
            return (T)sessionValue;
        }

        public void SetSessionValue(Expression<Func<T>> expression, T value)
        {
            var sessionKey = GetSessionKey(expression);
            Session[sessionKey] = value;
        }

        private string GetSessionKey(Expression<Func<T>> expression)
        {
            MemberExpression me;
            var body = expression.Body;
            if (body is MemberExpression)
            {
                me = body as MemberExpression;
            }
            else if (body is UnaryExpression)
            {
                var ue = body as UnaryExpression;
                me = ue.Operand as MemberExpression;
            }
            else
            {
                throw new NotImplementedException();
            }

            return "SessionManager_" + me.Member.ReflectedType + "." + me.Member.Name;
        }
    }

To use this I would simple create a property similar to this:

        public IList AnImportantProperty
        {
            get
            {
                return SessionManager.GetSessionValue(() => AnImportantProperty, new List());
            }
            set
            {
                SessionManager.SetSessionValue(() => AnImportantProperty, value);
            }
        }

Now my session is tidily hidden away. It will survive refactoring of the property name and guarantee a unique session name. To my eyes it looks clean, simple and D.R.Y.

I’ve written this a couple of times this morning:

if (string.IsNullOrWhiteSpace(Name))
{
    errors.Add(new KeyValuePair("Name", "Name must contain some text"));
}

if ((Name ?? "").Length > 50)
{
    errors.Add(new KeyValuePair("Name", "Name cannot be more that 50 characters long"));
}

I couldn’t help but feel that if I had to write this more than about twice I would go nuts, never mind the obvious maintenance problems. If I rename a property I want the correct property name in the errors collection, not the name of the property from 9 months ago.

So since all this validation is being done at the domain level and all my domain entities implement the interface IBaseEntity (come on EF, let me pick my own base class)  I decided I’d write myself a little validation function that would use lambdas to take a property and validate its value meets the constraints. So I did and ended up with the following function:

public static void ValidateRequiredFieldWithMaxLength(this IBaseEntity entity, Expression> e, int maxLength, IList> errors)
{
    if (errors == null)
    {
        throw new ArgumentNullException("errors");
    }

    MemberExpression member = (MemberExpression)e.Body;
    Expression strExpr = member.Expression;
    string propertyName = member.Member.Name;
    string value = e.Compile()();

    if (string.IsNullOrWhiteSpace(value))
    {
        errors.Add(new KeyValuePair(propertyName, string.Format("{0} must contain some text", propertyName)));
    }

    if ((value ?? "").Length > maxLength)
    {
        errors.Add(new KeyValuePair(propertyName, string.Format("{0} cannot be more than {1} characters long", propertyName, maxLength)));
    }
}

Which may not be immediately obvious to you, but the long and the short is that I can now call my validation functions like this:

this.ValidateRequiredFieldWithMaxLength(() => this.Code, 10, errors);

It’s not perfect and I might end up fiddling around with it a bit more, but for now I like it.

Just a quick one, but what do you think will be the output of this program? It’s not what I expected:

    class Program
    {
        static void Main()
        {
            CanILeak leakyRef = null;
            try
            {
                new CanILeak(cil => leakyRef = cil);
            }
            catch (Exception)
            {
                Console.WriteLine("Exception");
            }
            if (leakyRef != null) 
                leakyRef.AreYouStillThere();

            Console.ReadLine();
        }
    }

    class CanILeak
    {
        public CanILeak(Action fail)
        {
            fail(this);
            throw new Exception();
        }

        public void AreYouStillThere()
        {
            Console.WriteLine("I'm still here");
        }
    }

I’ve been hacking around with database migrations and decided to give MigratorDotNet a go. The first problem I found was that I had to manually number the migrations. The trick of using the migration attribute with the current date and time formatted as yyyyMMddhhssfff works a charm, but is a pain to type more than once.

So to solve the problem I’ve created a code template that gives you something like this as a shell:

using System.Data;
using Migrator.Framework;

namespace MigrationLibrary
{
[Migration(201003040752265)]
public class Migration1 : Migration
{
public override void Up()
{
throw new System.NotImplementedException();
}

public override void Down()
{
throw new System.NotImplementedException();
}
}
}

To install it you need to do a couple of things, take the dll from in here and register it in your GAC and then take this zip and drop it into “\Visual Studio 2010\Templates\ItemTemplates\Visual C#”. Restart Visual studio and you can now add a migration from the new item menu.

I’ve only tried this in visual studio 2010 and have done no real testing. License wise, let people know I wrote it. If it breaks your machine, steals your financial identity, runs off with your wife and then crashes your car into a wall, it’s your own fault for running code you found on the internet. You have been warned.

The longer you use asp.net webforms the more likely it is that you will see this:

Exception type: System.ArgumentException

Exception message: Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation=”true”/> in configuration or <%@ Page EnableEventValidation=”true” %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

If you’re lucky enough to have it happen on a dev machine and you know which control is causing the problem you’re most of the way to tracking down the error. Just read this, this and this.

If like me, you can’t track it down, all you’re getting is vague error reports and users who can’t remember what they did (or curiously didn’t even see the error) then you need to know which control actually caused the error.

This is what I did:

Imports System.Net.Mail

Namespace Code.Controls

    Public Class TrackingLinkButton
        Inherits LinkButton

        Protected Overrides Sub RaisePostBackEvent(ByVal eventArgument As String)
            Try
                MyBase.RaisePostBackEvent(eventArgument)
            Catch argExc As ArgumentException
                SendPostbackError(argExc)
            End Try
        End Sub

        Private Sub SendPostbackError(ByVal argExc As ArgumentException)

            Dim subject As String = "ArgumentException: Additional info"
            Dim body As String = String.Format("Exception was caused by the control with ID: {0} and clientId of: {1}", _
                                               Me.ID, Me.ClientID)

Dim msg As New MailMessage("from@somesite.com", "support@somesite,com", _

                                       subject, body)

Dim client As New SmtpClient() client.Send(msg) End Sub End Class End Namespace
And hooked it in with this:

<tagMapping>
	<add tagType="System.Web.UI.WebControls.LinkButton"
		mappedTagType="AcademyPro.Code.Controls.TrackingLinkButton"/>

</tagMapping>

Now all I have to do it sit back and wait for the email to fire and I should be able to track down the error (I hope).

Roy Osherove is giving an hands-on TDD Masterclass in the UK, September 21-25. Roy is author of “The Art of Unit Testing” (http://www.artofunittesting.com/), a leading tdd & unit testing book; he maintains a blog at http://iserializable.com (which amoung other things has critiqued tests written by Microsoft for asp.net MVC – check out the testreviews category) and has recently been on the Scott Hanselman podcast (http://bit.ly/psgYO) where he educated Scott on best practices in Unit Testing techniques. For a further insight into Roy’s style, be sure to also check out Roy’s talk at the recent Norwegian Developer’s Conference (http://bit.ly/NuJVa).

Full Details here: http://bbits.co.uk/tddmasterclass

bbits are holding a raffle for a free ticket for the event. To be eligible to win the ticket (worth £2395!) you MUST paste this text, including all links, into your blog and email Ian@bbits.co.ukwith the url to the blog entry.  The draw will be made on September 1st and the winner informed by email and on bbits.co.uk/blog

If you have a web form and don’t want a users input to be saved by a browser for repeated entry later then you need to employ autocomplete attribte of a form.

The HTML below will give you a simple form that the browser should not prompt the user to save the credentials.

You should note, this is not standards compliant, but it does seem to work in chrome, IE and firefox.

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”

    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”&gt;

<html xmlns=”http://www.w3.org/1999/xhtml&#8221; xml:lang=”en” lang=”en”>

    <head>

        <title>Prevent Autocomplete</title>

    </head>

    <body>

    <form id=”payment” autocomplete=”false” action=”#” method=”post”>

        <p><label for=”Name”>Name on Credit Card</label><input type=”text” id=”Name”/></p>

        <p><label for=”CCNum”>Creditcard Number </label><input type=”text” id=”CCNum”/></p>

        <p><label for=”Expiry”>Expiry Date</label><input type=”text” id=”Expiry”/></p>

        <input type=”submit” />

    </form>

    </body>

</html>

The auto complete extender comes as part of the AjaxControlToolkit, it’s a really neat little extension to a TextBox that allows a user to be given suggestions based on what they type.

It is currently restricted so that it only shows text and no more. I’ve made a couple of changes that allow you to pass arbitrary html, which makes things a like more interesting.

Ok, so in the first thing I need to be able to do is pass the html from the webservice. This bit is easy, all we need to do is create an overload to AutoCompleteExtender. CreateAutoCompleteItem method. That’s easy, just add the following method to the AutoCompleteExtender class:

public static string CreateAutoCompleteItem(string text, string value, string markup)
{
return new JavaScriptSerializer().Serialize(new Pair(text, new Pair(value, markup)));
}

Now we need to make sure that the html is displayed, this is done by the _update method in AutoCompleteBehavior.js. In this method there is a loop, this spins through each of the list items that comes back from the web service. Essentially I detect if html is supplied and if it is then use the html, rather than simply putting a text node in place.

The other change is to the _setText function, this must search through the parent nodes to find which one has the text and id values which we sent from our web service.

The two files are attached, take them and drop them into your project, all your old code should continue to work, but you could write a web service like this to display html:

Public Function GetPersonList(ByVal prefixText As String, ByVal count As Integer) As String()

Dim table As DataSet
table = Database.Fill(“PersonSearch”, New SqlParameter() { _
Database.CreateParameter(“@Name”, SqlDbType.NVarChar, ParameterDirection.Input, prefixText), _
Database.CreateParameter(“@Count”, SqlDbType.Int, ParameterDirection.Input, count)})

Dim list(table.Tables(0).Rows.Count – 1) As String
Dim html As String

For i As Integer = 0 To list.Length – 1

html = String.Format(”

{0} {1}

“, _
table.Tables(0).Rows(i)(“Forename”), _
table.Tables(0).Rows(i)(“Surname”))

list(i) = AutoCompleteExtender.CreateAutoCompleteItem(String.Format(“{0} {1}”, table.Tables(0).Rows(i)(“Forename”), table.Tables(0).Rows(i)(“Surname”)), _
String.Format(“{0}”, table.Tables(0).Rows(i)(“PersonId”)), _
html)

Next

Return list

End Function

That’s it, you now have a list of people, with a picture next their name, which is nice.

I hope this helps someone.

Here’s the complete modified AutoCompleteBehavior.js: http://www.mediafire.com/?4ztezjxnfnl

and the modified AutoCompleteExtender.cs: http://www.mediafire.com/?5idmqczandm

I’m going to assume that by the point you are reading this article you already know what viewstate is, why it will cause you problems and what you should have already done about it.

If you haven’t then start by reading this post:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx

Turn ViewState off

The best thing you can do is to turn ViewState off. You can do this by turning it off on the whole site by editing your web.config file:

<pages enableViewState=false /> 

You can turn it off on a page:

<%@ Page Language=”C#” EnableViewState=”false” %>

Or you can disable on individual controls:

<asp:GridView EnableViewState=”false”></ asp:GridView >

On the face of it that’s the problem solved, wrong, dead wrong. Some controls will ignore the fact that ViewState is disabled and still use it any way. The GridView is one of the more notable examples. Also, you may find that this is not practical. You may need to use ViewState, you may have third party controls that require ViewState. Or simply you may have inherited a large site that makes use of ViewState extensively and removing it would take too much time.

Get Rid of ViewState Completely

Ok, so luckily the boys who wrote asp .net had their heads screwed on, in the Page object we are given two methods that we can override:

protected override void SavePageStateToPersistenceMedium(object state)

protected override object LoadPageStateFromPersistenceMedium()

Each and every page cycle these two methods are called. All we need to do is override the default behavior and do something else.

The following code gives us two alternatives to the default behavior, we can either move the ViewState into the session object, or if that’s no good we can compress the ViewState and send a smaller packet instead.

To use it, simply change your page to inherit from TheOldSewingFactory.ViewstateSample.BasePage rather than the standard System.Web.UI.Page.

Then on your page you can set the property ViewStateMode or you can add a new appSetting:

<appSettings>

<!–This setting can be “session”, “compress” or “default” –>

<add key=”ViewStateMode” value=”compress”/>

</appSettings>

Let me know what you think.

using System;
using System.Configuration;
using System.ComponentModel;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Web.SessionState;
using System.Web.UI;
 

namespace TheOldSewingFactory.ViewstateSample
{
    public enum ViewStateConfig
    {
        Session,
        Compress,
        Default,
        NotSet
    }

    public partial class BasePage : System.Web.UI.Page
    {
        private const string ViewStateModeSetting = "ViewStateMode";
        private const string ViewStateSessionId = "ViewStateSessionId";
        private const string CompressedViewStateId = "CompressedViewState";

        private ViewStateConfig _viewStateMode = ViewStateConfig.NotSet;
        [Browsable(true)]
        [Category("Behaviour")]
        [DefaultValue(ViewStateConfig.NotSet)]
        public ViewStateConfig ViewStateMode
        {
            get
            {

                //The setting on the page overrdes the one on the site config.
                if (_viewStateMode != ViewStateConfig.NotSet)
                {
                    return _viewStateMode;
                }
                else if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings[ViewStateModeSetting]))
                {
                    return (ViewStateConfig)Enum.Parse(typeof(ViewStateConfig), ConfigurationManager.AppSettings[ViewStateModeSetting], true);
                }
                else
                {
                    return ViewStateConfig.Default;
                }
            }
            set
            {
                _viewStateMode = value;
            }
        }

        protected override void SavePageStateToPersistenceMedium(object state)
        {
            switch (ViewStateMode)
            {
                case ViewStateConfig.Session:
                    //Since the session isn't always availible, we had better make sure we
                    //do something sensible
                    if (this.Session.Mode != SessionStateMode.Off)
                    {
                        this.SaveToSession(state);
                    }
                    else
                    {
                        this.CompressViewstate(state);
                    }
                    break;
                case ViewStateConfig.Compress:
                    this.CompressViewstate(state);
                    break;
                default:
                    base.SavePageStateToPersistenceMedium(state);
                    break;
            }
        }

        protected override object LoadPageStateFromPersistenceMedium()
        {
            switch (ViewStateMode)
            {
                case ViewStateConfig.Session:
                    if (this.Session.Mode != SessionStateMode.Off)
                    {
                        return this.LoadFromSession();
                    }
                    else
                    {
                        return this.DecompressViewstate();
                    }
                case ViewStateConfig.Compress:
                    return this.DecompressViewstate();
                default:
                    return base.LoadPageStateFromPersistenceMedium();
            }
        }

        private void SaveToSession(object state)
        {
            //First lets see if there is already a session id availible to us
            string viewStateSessionId = base.Request.Form[ViewStateSessionId];
            if(string.IsNullOrEmpty(viewStateSessionId))
            {
                //If there isn't then we'll be needing one.
                viewStateSessionId = Guid.NewGuid().ToString();
            }

            //Save the data into our session object
            Session[viewStateSessionId] = state;

            //Lastly we save the sessionid for when the page is loaded.
            ScriptManager.RegisterHiddenField(this, ViewStateSessionId, viewStateSessionId);
        }

        private object LoadFromSession()
        {
            return Session[base.Request.Form[ViewStateSessionId]];
        }

        private void CompressViewstate(object state)
        {
            //The ObjectStateFormatter is explicitly for serializing
            //viewstate, if you're using .net 1.1 then use the LosFormatter

            //First off, lest gets the state in a byte[]
            ObjectStateFormatter formatter = new ObjectStateFormatter();
            byte[] bytes;
            using (MemoryStream writer = new MemoryStream())
            {
                formatter.Serialize(writer, state);
                bytes = writer.ToArray();
            }

            //Now we've got the raw data, lets squish the whole thing
            using (MemoryStream output = new MemoryStream())
            {
                using (DeflateStream compressStream = new DeflateStream(output, CompressionMode.Compress, true))
                {
                    compressStream.Write(bytes, 0, bytes.Length);
                }

                //OK, now lets store the compressed data in a hidden field.
                ScriptManager.RegisterHiddenField(this, CompressedViewStateId, Convert.ToBase64String(output.ToArray()));
            }
        }

        private object DecompressViewstate()
        {
            //First lets get ths raw compressed string into a byte[]
            byte[] bytes = Convert.FromBase64String(Request.Form[CompressedViewStateId]);

            using (MemoryStream input = new MemoryStream(bytes))
            {
                //Now push the compressed data into the decompression stream
                using (DeflateStream decompressStream = new DeflateStream(input, CompressionMode.Decompress, true))
                {
                    using (MemoryStream output = new MemoryStream())
                    {
                        //Now we wip through the decompression stream and pull our data back out
                        byte[] buffer = new byte[256];
                        int data;
                        while ((data = decompressStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, data);
                        }

                        //Finally we convert the whole lot back into a string and convert it
                        //back into it's original object.
                        ObjectStateFormatter formatter = new ObjectStateFormatter();
                        return formatter.Deserialize(Convert.ToBase64String(output.ToArray()));
                    }
                }
            }
        }
    }
}