Apr 01 2012

ASP.NET MVC: an improved comma-separated-values array model binder

Category: Uncategorizedzvolkov @ 2:25 pm

This is my improved CSV array/IEnumerable ModelBinder. It is mostly based on Nathan Taylor’s work with following improvements:

  1. Nathan’s binder could only bind sub-properties of complex models, while mine can also bind individual controller arguments.
  2. My binder also gives you correct handling of empty parameters, by returning an actual empty instance of your array or IEnumerable.

To wire this up, you can either attach this to an individual Controller argument:

[ModelBinder(typeof(CommaSeparatedModelBinder))]

…or set it as the global default binder in Application_Start in global.asax.cs:

ModelBinders.Binders.DefaultBinder = new CommaSeparatedModelBinder();

In the second case it will try and handle all IEnumerables and fall back to ASP.NET MVC standard implementation for everything else.

Behold:

public class CommaSeparatedModelBinder : DefaultModelBinder
{
	private static readonly MethodInfo ToArrayMethod = typeof(Enumerable).GetMethod("ToArray");

	public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
	{
		return BindCsv(bindingContext.ModelType, bindingContext.ModelName, bindingContext)
				?? base.BindModel(controllerContext, bindingContext);
	}

	protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
	{
		return BindCsv(propertyDescriptor.PropertyType, propertyDescriptor.Name, bindingContext)
				?? base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
	}

	private object BindCsv(Type type, string name, ModelBindingContext bindingContext)
	{
		if (type.GetInterface(typeof(IEnumerable).Name) != null)
		{
			var actualValue = bindingContext.ValueProvider.GetValue(name);

			if (actualValue != null)
			{
				var valueType = type.GetElementType() ?? type.GetGenericArguments().FirstOrDefault();

				if (valueType != null && valueType.GetInterface(typeof(IConvertible).Name) != null)
				{
					var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(valueType));

					foreach (var splitValue in actualValue.AttemptedValue.Split(new[] { ',' }))
					{
							if(!String.IsNullOrWhiteSpace(splitValue))
								list.Add(Convert.ChangeType(splitValue, valueType));
					}

					if (type.IsArray)
						return ToArrayMethod.MakeGenericMethod(valueType).Invoke(this, new[] { list });
					else
						return list;
				}
			}
		}

		return null;
	}
}

 


Apr 01 2012

ASP.NET MVC: build URL based on current URL

Category: Uncategorizedzvolkov @ 2:12 pm

In my current ASP.NET MVC project, I often need to build URLs in my Razor views. While most of them are Action URLs — with only area, controller, and action specified, sometimes I need to build a URL based on the current URL, with some of the parameters modified. This is mostly used for tabs, or views — multiple related screens highlighting different aspects of the same entity the user is interacting with.

If all you need is to modify your Action, while keeping the rest of the route the same, you can simply use @Url.Action method — it will actually reuse your current route data while overriding the Action (and, optionally, Controller name).

However, in more complex scenarios you may have bunch of parameters specified in your query string, which you want to preserve. Or, you want to keep Action/Controller but substitute the Id for another value. Or you may even have a non-standard routing scheme. In such cases I saw my colleagues resorting to ad-hoc querying of RouteData and even (gasp!) string concatenation!

Having tired of seeing this dirt all over my project, I came up with this generic helper method. Here is how you use it:

window.location.href = '@Url.Current(new {years = 3})';

This will:

  1. get the current URL (including area, controller, action, id, query string and anything else),
  2. add or replace the parameter(s) you specify,
  3. find the best matching route!
  4. stick as many parameters in the route slots as possible.
  5. throw the rest of the parameters in the query string

For enthusiasts, here is the source code:

public static class UrlHelperExtensions
{
	//Builds URL by finding the best matching route that corresponds to the current URL,
	//with given parameters added or replaced.
	public static MvcHtmlString Current(this UrlHelper helper, object substitutes)
	{
		//get the route data for the current URL e.g. /Research/InvestmentModelling/RiskComparison
		//this is needed because unlike UrlHelper.Action, UrlHelper.RouteUrl sets includeImplicitMvcValues to false
		//which causes it to ignore current ViewContext.RouteData.Values
		var rd = new RouteValueDictionary(helper.RequestContext.RouteData.Values);

		//get the current query string e.g. ?BucketID=17371&compareTo=123
		var qs = helper.RequestContext.HttpContext.Request.QueryString;

		//add query string parameters to the route value dictionary
		foreach (string param in qs)
			if(!string.IsNullOrEmpty(qs[param]))
				rd[param] = qs[param];

		//override parameters we're changing
		foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(substitutes.GetType()))
		{
			var value = property.GetValue(substitutes);
			if (string.IsNullOrEmpty(value)) rd.Remove(property.Name); else rd[property.Name] = value;

		//UrlHelper will find the first matching route
		//(the routes are searched in the order they were registered).
		//The unmatched parameters will be added as query string.
		var url = helper.RouteUrl(rd);
		return new MvcHtmlString(url);
	}
}

Basically, the idea is to start with the current RouteData, throw in all QueryString parameters, and optionally add or replace any user-provided arguments. I also give special treatment to the empty values of parameters — this way you can remove a parameter if needed by setting it to an an empty string. Resulting RouteData dictionary is then matched against the routing table by the UrlHelper.RouteUrl. Note: the routes are searched in the order they’re registered so be sure to register more specific routes first!


Feb 24 2012

Enlightened Development: 9 not so obvious software development principles learned the hard way

Category: Uncategorizedzvolkov @ 8:57 pm

My response to Agile Manifesto, the M.f.S.C. and the like.

This is called “Enlightened Development: 9 not so obvious software development principles learned the hard way”.

We play by our own rules.

From experience we know: in any game, playing by the rules is more fun. Inspired by Kanban and Scrum we come up with our own game rules. The rules give predictability and protect us from our human emotions like panic or greed. Instead of breaking the rules or ignoring them, we adjust our rules, as often as necessary.

We solve fundamental problems first.

From experience we know: a house built on a shaky foundation can be finished faster, but who would want to live in it? We use business requirements as the initial impulse to discover the fundamental problem. Having solved the fundamental allows us to propose solutions to whole classes of problems the business didn’t even think about.

We communicate everything to everybody.

From experience we know: software project can only move as fast as the information exchanged between its team members. We’re religious about keeping every team member in the loop before decisions are finalized, so they can give their advice, adjust their plans, or veto the whole thing. We identify and eliminate communication barriers: time, space, language, culture. We choose names for things and stick with them. We cut through the bullshit.

We solve one problem at a time.

From experience we know: multitasking is good for tasks that require no thinking, software engineering is not one of them. This is why, instead of assigning multiple tasks to every person, we gang up against one problem at a time. This minimizes communication waste, improves quality, reduces rework, and saves everybody’s time. We kill one bird with one stone, again and again and again.

We give developers respect they deserve.

From experience we know: treating “the business” as a customer whose every wish is a command for development is a bad way to evolve sustainable architecture. Software being the face of the sales and the heart of the operations, we expect professionals to collaborate to find the best solution to each problem. PMs and BAs exist to take non-technical burden off developers, so they can focus on solving the essential problems.

We seek feedback and act on it.

From experience we know: there is always room for improvement. We’re harsh to ourselves and encourage others to be outspoken about our shortcomings. We use group accountability and shared vision as a way to protect individuals from stress associated with continuous improvement. The feedback is not merely a vent for frustration. Knowing that every complaint has an actual cause behind it we actually act on every single one.

We don’t commit to dates.

From experience we know: in software development the deadlines are lies. We don’t lie to ourselves or our customers, that’s why we don’t commit to dates. We don’t need a stick of deadline to keep us stimulated; instead we work our best every hour of every day, arriving at the best product in the shortest time possible.

We simplify.

From experience we know: simplicity is an exhaustible resource, and over-complication is not sustainable. The best solutions are built from small number of simple pieces that can be combined together in an infinite number of ways. We strive to keep our software and our UIs simple. We’re happy if we can cut out 80% of extra complexity by only solving 80% of the problem. We don’t confuse “easy” with “simple”, and we take time to solve problem in a simple way so we can keep moving fast in the future.

We master the economics of time.

From experience we know: in software development, money are cheap, time is expensive. Invested time today, got more free time tomorrow — that’s a profit. Ended up with more maintenance taking up a portion of your future time — you’re at loss. This simple economics of time is what drives our software architecture and task prioritization. This is why we automate the hell out of every manual operation to be performed by a developer and don’t allow any overhead to creep in.


Feb 06 2012

my list of issues with this company

Category: Uncategorizedzvolkov @ 6:23 pm

If this sounds a bit harsh, negative, naive ecetera, please keep in mind this is coming from a non-native English speaker (a Russian!), so the virtue of subtlety of expression may not fully manifest in author’s foreign writing.

Also, if you despise the “give me this now” attitude, remember that the author is an immigrant: indeed, he left his own country in hope to find a better society! Now, instead of doing the same in this case, I’m trying to make the difference as much as I can, both hands-on, and by writing analytic emails / posts like this one.

Finally, what goes below is my personal opinion, and as any opinion it maybe biased, one-sided, or outright wrong. However, at some point in my life I decided, paraphrasing Plato, that the life w/o opinions is not worth living. Besides, what would remain of the declared superiority of capitalism / democracy over communism if we were deprived of our opinions?

With all due disclaimers, here is my opinion of this company.

The Good

  • Strong development team
  • Friendly culture
  • Great work/life balance
  • Relatively recent technologies (for a Microsoft shop)
  • No problems w/ purchasing 3rd party dev tools
  • Developers do not report to PMs
  • No unneeded bureaucracy
  • Developers manage their dev environment however they like
  • If developers take effort and responsibility to innovate, the business does not actively resist

The Bad

  • No respect for game rules, no understanding why we need them

    • Single decision maker aka benevolent tyrant
    • No single written down backlog
    • Ad-hoc requests and prioritization
    • Scrum breaks down as soon as dev team stops applying pressure to support it
    • No code freeze nor feature freeze, combined with big infrequent releases
  • No technical strategy, no understanding why we need one

    • Greedy for new features w/ no respect for adding more technical debt
    • No understanding of iterative approach in terms of functional vs. auxiliary features
    • No desire to evolve sustainable architecture
    • No desire to pay back technical debt
  • Weak BA/PM skills

    • Some are still stuck in the Waterfall/RUP w/o even realizing it. Barely familiar with Scrum / Kanban and only supporting it when the initiative comes from development.
    • Sometimes still struggling with fundamentals like mockups, well-structured user stories etc.
    • Lacking ability to build conceptual models as opposed to user-facing screens.
    • Not willing to learn / improve and not seeing the need.
  • No understanding, outside of development, that we are a SaaS company

    • No dedicated production operations team, no understanding why we need one
    • Inadequate IT staff for a SaaS company
    • IT resisting dev efforts to automate deployments

The Ugly

To summarize, in this company the pressure from “the business” is applied in the direction of increasing entropy: breaking the process and destroying software infrastructure, instead of building it up. If development team gave up to the pressure, in about 3-5 years the company’s computer systems would regress to the point where more effort would be required to keep the systems functional than to make any progress.

The only way developers can succeed in such an environment is by treating “the business” as noise while secretly doing what they think is right.

You would think it should be a common knowledge that for a company to succeed, developers and “the business” should be on the same side. However, the opposite seems to be the case. As an ex-rockstar Hanselman used to put it,  If you’re not getting in trouble with your boss at least twice a year, you’re likely not pushing the envelope hard enough.


Jan 17 2012

IO-style cloning in Javascript

Category: Uncategorizedzvolkov @ 5:31 pm

In true prototype languages like IO, there is no inheritance vs. instantiation of classes, there is differential inheritance aka cloning. New objects are derived from existing objects. The old object serves as a prototype of the new one.

In Javascript there is no proper cloning — instead, a prototype to be assigned to a freshly created object depends on the prototype property of the constructor function. All the elements are there but they are insanely incoherent.

To take Crockford’s Object.create pattern one micro-step closer to IO, here’s how IO-style cloning can be implemented in Javascript:

var yobject = {
  derive : function () {
    var F = function() {};
    F.prototype = this;
    return new F();
  }
};

Now the objects (or, rather, “yobjects”) can be easily cloned like this:

var car = yobject.derive();
car.wheels = 4;
var ferrari = car.derive();
ferrari.color = red;
console.log(ferrari.wheels); //prints 4

You can even implement singleton pattern, IO-style:

var elvisCadillac = car.derive();
elvisCadillac.color = 'pink';
elvisCadillac.clone = function () {return this;};

var fake = elvisCadillac.derive();
console.log(fake === elvisCadillac ); //prints true

I thereby name you The Yobject Pattern!


Jan 15 2012

Teaching Assembly, Part 2

Category: Uncategorizedzvolkov @ 12:36 pm

Just to dump my thoughts on the subject, and clean the brain buffer for new ideas, I’m writing this post summarizing what I taught my son since the last post:

  • Learned the notion of video memory. Drew a stickman by setting bits in video memory. Made the stickman “move” by erasing and redrawing it with an offset.
  • Made a “font” consisting of binary representation of pixels required to draw letter “A”. Learned to “print” strings consisting of A’s. Discussed what it would take to print arbitrary strings this way.
  • Learned the notion of ASCII code as a way to represent characters in memory.
  • Called CP/M system function to print a $-terminated string.

Now, in our first phase, all programming was done in CP/M’s debugger “SID”, running on an 8080 emulator. The idea was to start with simple non-segmented addressing, understand limitations of 8-bit arithmetic, and overall get used to a highly restricted environment the assembler programmer works in. At some point I realized it wasn’t our primary goal to learn CP/M and decided to upgrade to 8086.

Here’s what we learned on 8086:

  • Learned that DOS command DEBUG — DOS equivalent of CP/M’s SID — still works on Windows XP (and even on 32-bit Windows 7 or so I was told!). Played with DEBUG to learn its slightly different commands and output format. Turns out there’s an improved clone of DEBUG called GRDB.
  • 8086 registers. All 16 bit. Many accumulators. Extra registers.
  • 8086 versatile MOV commands and the [xyz] notation. No need to remember 8080′s LXI/LDAX bullshit.
  • 8086 built-in multiplication and division
  • File system basics. Directories and files. Path. Commands CD and DIR. The process of loading executable file into memory and starting it.
  • 8086 has lots of RAM. Segment addressing. Why segments “overlap” (or, rather, can start anywhere on 16 byte boundary). Tiny model vs. small model.
  • DOS equivalent of CP/M’s print functions (Interrupt 21h, same function #9). Same $-terminated strings.
  • Rewrote a couple of previously written programs (e.g. reversing an array) from 8080 assembler into 8086.
  • Learned to save a program from DEBUG into a .COM file.
  • The notion of source code vs. executable. Compilation. Wrote a “hello world” in .asm file and compiled it to .COM using MASM.
  • A DOS Int 21 function to input a character.
  • Wrote a console game (!) that guesses a number from 1 to 1000 by progressively cutting the range in half.
  • Representation of negative numbers. Two’s complement format.

This was a time when I almost decided that we were done and it was time to move on to C. I even showed Matthew hello world in C and he liked how you don’t need to juggle registers and how printf magically formats strings and numbers. But then I realized: first, I was rushing a bit and perhaps we need to stay on assembler until he gets comfortable writing programs w/o my help. Most importantly, I realized C was not exactly meant for “fun” programming — it is perfect for processing files but less perfect for drawing on screen, or for making sounds, or for developing micro-games, not without using third-party libraries anyway. I really believe I should avoid the libraries as they will certainly overwhelm Matthew (“look these people have already written EVERYTHING there was to be written!”).

And so I this morning I decided to linger on assembler a bit longer. Here’s what we learned in the last few days:

  • The notion of global constants (the strings we print) vs. global variables. Rewrote the game to take advantage of global variables as opposed to holding stuff in registers all the time.
  • The notion of local variables on stack.
  • Intel 80386. 32-bit registers.
  • Modern debuggers: IDA Pro and OllyDbg.
  • FASM (Flat assembler) as a simpler, more modern alternative to MASM. FASMW IDE.
  • The boot process. BIOS vs. OS.
  • Interrupts. Actual (hardware interrupts) vs. interrupts as system API.
  • DOS interrupts and BIOS interrupts vs. directly working with hardware.
  • Keyboard scan codes. Difference between scan- ASCII- codes.

Now I’m thinking we should develop a console game that would involve moving an object on screen with cursor keys. Perhaps such a game as Snake or Sokoban or Arcanoid would work well. Any ideas?