Declarative querystring parameter binding – codeproject

This article discusses a strategy for automatic population of instance fields and properties on an ASP.NET page from parameters supplied via properties of the Request object ( .QueryString, .Form etc…). Fluid in middle ear symptoms The Problem

If you have parameterized ASP.NET pages – i.e. Draining fluid in ear pages that modify their output on the basis of some input from the GET ( Request.QueryString) or POST ( Request.Form) parts of the request – then you probably spend a lot of time writing parameter retrieval code, which probably started out like this: protected string FirstName{

…but then you have to deal with the potential of FirstName being null throughout the rest of your code, so you probably supply a default empty value, by rewriting like this (Note: handy IsNull method, we’ll be using throughout the code): protected static string IsNull( string test, string defaultValue){

This approach works fine for non-string types too, you’ve just got to add your Convert.ToXXX() statement into your property, and decide what to do when the parameter is null – supply a default, or throw an exception: protected int CustomerID{

Yuk. Fluid in inner ear What started out as a simple accessor is starting to grow a bit. Ear and jaw pain on left side Also that code’s running every time we access CustomerID – so that’s unnecessary overhead – and it doesn’t run till you first access it, so you get halfway through your (expensive?) process before that exception gets thrown.

It’s probably about this point that we refactor the whole mess, and do all this work upfront in the Page_Load (or the end of OnInit): private void Page_Load( object sender, System.EventArgs e) {

Now you’ve only got to do this a couple of times, and there’s a clear pattern emerging. Fluid behind eardrum in adults symptoms Whether you’re populating fields or properties (i.e. Remedy for fluid in ear ViewState wrappers), there’s a couple of standard actions going on:

Now, I wouldn’t be a proper coder if I wasn’t lazy, and when it comes to this kind of boring repetitive stuff, I’m well lazy.

Fluid in ear remedy So what’s the alternative? The Solution: Declarative Parameter Binding

Well, one solution would be to just ‘mark up’ the fields and properties we want loaded with appropriate metadata (specifying defaults, what key to bind against and in which collection) and just let some library code perform the actual work.

The optional constructor parameter just supplies the key to find the parameter in the Request.QueryString collection, and the IsRequired property toggles whether omissions are an exception condition, rather than a skip condition.

All of a sudden, a great mass of code has condensed into a few attributes, which makes it easier to see at-a-glance what’s going on, and simpler to maintain. Fluid in your ear All we need to do now is implement all that common logic we just trimmed out in some kind of helper class. Fluid in ears allergies This would use reflection to examine the Page class, find all the properties (or fields) we marked with the attributes, and make the relevant assignments from QueryString automatically.

• MemberInfo subclasses provide a way of performing ‘late bound’ interactions with object members, rather than having to pre-specify what’s going to be performed at compile-time. Symptoms of fluid in the ear So a PropertyInfo allows you to do get/ set’ing of that property on an object, without having to hard-code object1.property1=myValue into your source.

The first step is to do exactly that, just loop through the properties and members on the class (here assigned to target), and pass each member (along with the current HttpRequest ( request)) down to another method that’s actually going to do the work. Sinus drainage in ear public static void SetValues( object target, System.Web.HttpRequest request)

The only slightly confusing bit of this step is that we merge the properties and fields arrays into one members array, which just means we only have to do one loop round. Ear and tooth pain on one side All the real work gets done in SetValue (singular!), which we’ll discuss next. Fluid in ears in adults Now there’s a fair chunk of code here, but what it does is fairly straightforward when broken down.

Firstly, we exclude members that aren’t marked with WebParameterAttribute (the outermost if), and because there’s no simple way of dealing with indexed parameters, we throw an error if they’ve been marked (you might choose to just skip the member silently): public static void SetValue(MemberInfo member,

Now we get the various settings from the attribute, and the (string) parameter value itself. Ear and jaw pain after tooth extraction // There should only be one // WebParameterAttribute (it’s a single-use attribute)

Note that it’s the attribute itself which supplies the actual parameter value we’re after, making its own determination on which part of the HttpRequest to use. Fluid in the ear in adults Delegating responsibility for non-core activities like this makes for a more flexible solution. Fluid in ear symptoms in adults In our case WebParameter – the only attribute we’ve talked about so far – selects either Request.Form or Request.QueryString depending on the method which was used to submit the form. Jaw pain on left side near ear Alternatively other, specialized, subclasses like QueryParameter and FormParameter can perform binding to specific parts of the request, and others could be easily created for Request.Cookies or Request.Session as required.

Now (finally), we can actually take our string and assign it to the member. Symptoms of fluid in ear We’ve got a couple of helper methods here just to make the code simpler (I won’t reproduce the full source code here, but it’s all in the example files):

I’m using a TypeConverter to do the actual string conversion, because this delegates responsibility for the string parsing to the outside world (which is always a good idea). How to get rid of fluid in inner ear If you haven’t come across them, the bottom line is that they’re a completely extensible scheme to associate type conversion routines with the types they convert to/from. Fluid in ear symptoms They’re principally used in control development (that’s how the VS.NET IDE’s property browser works), but they’re far too useful to only use in the designer and I’ve started using them all over. Ear jaw and neck pain on left side // Now assign the loaded value onto the member, // using the relevant type converter // Have to perform the assignment slightly // differently for fields and properties

// We catch errors both from the type converter // and from any problems in setting the field/property // (eg property-set rules, security, readonly properties) // If we’re not already using the default, but there // is one, and we’re allowed to use it for invalid data, // give it a go, otherwise just propagate the error if (!usingDefault && attrib.IsDefaultUsedForInvalid

Now the obvious place for all this code would be in a base Page class, but I have a real issue with creating unnecessary Page subclasses, so the ‘engine’ for my implementation is just a static method on the WebParameter class itself. Signs of fluid in ears I felt a bit dirty putting quite so much code on an attribute class, but it’s not the end of the world. Relieve fluid in ear private void Page_Load( object sender, System.EventArgs e)

Having to call it explicitly like this also saves on the overhead when you don’t need it done, and means you get to choose when to bind: first time round; postback; every request – what you choose will depend on what your page does and whether you’re binding to field or viewstate property accessors. Fluid behind eardrum adults Full Example

Having imported the relevant namespaces (and assemblies) into a page, all that’s actually required to do all this is the very briefest of code (this is from the included example): public class WebParameterDemo : System.Web.UI.Page

Note also that it doesn’t just have to be the Page class you bind to, any class can be ‘bound’, though it’d be rare for something other than a UserControl to be bound to Request.Form or Request.QueryString directly (especially since you could provide a page-level property to indirect the binding).

Now, I was toying with using a similar approach to this for Console apps, but it turns out someone already did it (or something pretty similar), so if I’ve sold you on this, check out CommandLineOptions and ditch all that args[] parsing nonsense. Fluid in baby ears Thank you Gert. Fluid behind eardrum remedy Drawbacks

I like this approach a lot, it gives me more time for writing the complicated convoluted bits that get me out of bed in the morning. Fluid behind eardrum symptoms However it has one downside, and that’s performance. Fluid in the ear symptoms Like anything based on reflection, its going to be slower than the equivalent direct call; I loop through a lot of unnecessary properties looking for those that are bound (and the Page class is not exactly short on public properties); and I’m using TypeConverters to do my string-conversions, which is yet more reflection.

That being said, reflection’s only a bit slower than normal. Feeling of fluid in ear Sure you wouldn’t use it in your 3D rendering routines, but compared to the cost of your database access, wire-latency and other issues inherent in a web app and it’s nothing. Home remedies for fluid in ear All that ASP.NET data binding you’re using – that’s reflection based. Fluid buildup in ear Still, if you’re desperate, you could probably speed it all up by:

• Restrict the GetFields() / GetProperties() calls in WebParameterAttribute.SetValues() to only return members declared in your code behind ( BindingFlags.DeclaredOnly), rather than include all the base class members (NB: Since your code behind is itself sub-classed to build the final page, this means you’d have to pass its Type into GetValues as well).

Finally, I should point out that in real life, I didn’t hard-code the message into the exceptions like this – I stuck them in a resource file. Middle ear effusion symptoms Even though I don’t intend globalizing my application, it makes it a lot easier for people re-using the assembly (including myself) to alter the messages to suit their needs without having to trawl through the source code. Ear pain and headache on left side History

In the ‘normal’ world of OO programming, people believe in building little helper objects that can be used / aggregated within other classes to perform specific bits of functionality. Fluid behind eardrum treatment However, when it comes to ASP.NET, there’s way too much temptation to write your handy bit of common functionality as a base page class, with the obvious drawback that to use it you’ve got to derive from it, which means you’re not deriving from something else.

Additionally Page is a pain to subclass from – you’ve got properties and methods coming out of your ears and you can’t make anything abstract (or have any properties that return null unless you attribute them appropriately) or the designer chokes on it. Ear and throat pain on one side So your object hierarchy becomes a mess of virtual methods that throw exceptions along the lines of ‘this method should have been overridden in a subclass’. Middle ear effusion treatment Yuk. Get rid of fluid in ear On top of all this, the designer slows to a crawl since it has to create all the stuff your page creates (this is especially slow if there’s database access involved), and you might not get the .config file you expected for all the dependent assemblies.

My advice is to have a few base page classes, sure, but keep it simple, and aggregate as much as possible of the more complex stuff as helper objects (even if they have to get passed a reference to their containing Page).

now basiclyy we can do all of what you said above with the IDefaultValueProvider inteface have it just specify a method with a parameter, ‘ object GetDefaultValue(string Parameter)’, which provides the default value based on the name of the parameter.

keeps thigs quite tidy and adds lots of flexability while maintaining the declerative style and not forcing you to create a new class for each parameter that needs a non constant default value.