in .NET

How to create a dynamic object in C# to manage QueryStrings

One of the most important features in C# 4 is Dynamic types that enable you to create dynamic objects. The following is the definition of dynamic types from MSDN:

Visual C# 2010 introduces a new type, dynamic. The type is a static type, but an object of type dynamic bypasses static type checking. In most cases, it functions like it has type object. At compile time, an element that is typed as dynamic is assumed to support any operation. Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. However, if the code is not valid, errors are caught at run time.

Unfortunately, after about 2 years from Visual Studio 2010 and C# 4 release, most of C# developers don’t know how to use this feature! This is sad because I think dynamic types are one of the most useful features introduced in C# 4. In this post I’m going to show you a very simple use-case of Dynamic types:

As you know, getting a QueryString parameter is very easy in .NET. You can simply use Requst.QueryString[“{ParameterKey}”] to get the value of a QueryString parameter. By calling Request.QueryString, .NET looks for a QueryString item and returns the value of it if the key is available; otherwise, it’ll return null string.

With C#’s Dynamic feature, you create a class to access the QueryString parameter like the following:

QueryString.{ParameterKey};

To achieve this, you need to create a new QueryString class; and this class must inherit System.Dynamic.DynamicObject class. DynamicObject class is an abstract class and all of the objects with Dynamic functionality must inherit this class.

DynamicObject class has some methods that you can override in order get, set and delete Dynamic values. In this example I’m going to use “TryGetMember” method to get the value of a QueryString parameter.

TryGetMember method provides the implementation for operations that get member values. Classes derived from the DynamicObject class can override this method to specify dynamic behavior for operations such as getting a value for a property.

TryGetMember method has two parameters. The first one is “binder” and the second is “result”. The following is definition of each parameter by MSDN.

Binder:

Binder parameter provides information about the object that called the dynamic operation. The binder.Name property provides the name of the member on which the dynamic operation is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty) statement, where sampleObject is an instance of the class derived from the DynamicObject class, binder.Name returns “SampleProperty”.

Result:

Result parameter provides the result of the get operation. For example, if the method is called for a property, you can assign the property value to result.

So everything is very simple now! You can get a QueryString parameter using a Dynamic object. The following is the implementation:

public class DynamicQueryString : DynamicObject {
        public override bool TryGetMember(GetMemberBinder binder, 
        out object result) {
            var queryValue = string.Empty;
            queryValue = 
            HttpContext.Current.Request.QueryString[binder.Name];
            result = 
            string.IsNullOrEmpty(queryValue) ? string.Empty : queryValue;
            return true;
        }
 }

Now your Dynamic class is ready to use. You can use this class in a variety of ways but here’s what I prefer:

public class MyPage : System.Web.UI.Page {
        public dynamic QueryString {
            get { return new DynamicQueryString(); }
        }
}

All of my pages in my ASP.NET Web Forms application are inherited to this class so I easily can use my dynamic property. Below showing a page that inherits MyPage class and gets the QueryString parameter ID using dynamic types:

public class Default : MyPage {
    protected void Page_Load(object sender, EventArgs e) {
        Response.Write(this.QueryString.ID);
    }
}

Hope it helps.