ASP.NET C# - How to parse QueryString GET parameter arrays with square-bracket notation

ASP.NET C# - How to parse QueryString GET parameter arrays with square-bracket notation

Today I was playing with HTML tables in a ASP.NET C# MVC Web Application: since I had to implement some ajax-based parsing, sorting and filtering, I installed the awesome Tabulator JQuery plugin, which is among the few ones that supports all that.

Implementing it was rather easy, thanks to the great documentation and examples provided by the project's website. However, as soon as I was testing the filters, I struggled a bit to convince my server-side Controller to properly handle the auto-generated ajax URL used by the plugin to send the filters info issued by the client to the server:

This is a rather common notation syntax to pass "array-like" values within a GET request: the technique is usually called "square-bracket notation" and it's much similar to what you can do in loosely-typed scripting languages such as PHP and JavaScript, where you can define numeric and associative arrays in the following way:

... and so on: you don't have to worry about compilation-level errors there, as the type will be determined internally. Conversely, in strongly-typed languages such as ASP.NET's C# and Visual Basic.NET, these types need to be determined right from the definition.

The Issue

The aforementioned concept is strictly related to our initial problem: as a matter of fact, the binding logic used by MVC to convert the Query String of a GET Request into strongly-typed parameters also needs to be instructed properly. In other words, we cannot do this:

Because the default MVC property binder won't be able to do its job properly: the filters string will be always set to null, because there's nothing in the query string that can be treated like a string.

And the following won't work either:

We would just end up with an empty  filters  object, as the property binder won't know how to properly "box" the received parameter array(s).

(If you don't know what boxing is, read here for more info - otherwise, keep reading).

The Workaround(s)

As we most likely already know, all the query string parameter value(s) can be also retrieved directly from the Request.QueryString  collection. However, it won't be a walk in the park, as they will be split up into many different key-values items (one for each inner value):

ASP.NET C# - How to parse QueryString GET parameter arrays with square-bracket notation

That's far from ideal.

We could try to normalize this outcome by parsing the QueryString in a different way: however, the HttpUtility.ParseQueryString()  and the UriExtension.ParseQueryString()  methods won't help us, as they both return a NameValueCollection object, which is basically a collection of string keys and string values... And our filters  object is definitely not a string.

Our only option to get these values in a decent fashion would be to implement a custom (and rather complex) QueryString parser... and it won't be easy. Luckily enough, the MVC framework does provide much better alternatives to deal with our issue.

The Fix

For standard arrays of strings and/or numbers, the solution would be something like this:

However, in our specific scenario that won't work either: we're not dealing with a simple array of strings: our   filters  object is actually a two-dimensional array. To be even more precise, it's an array of name-value pairs. 

Once we understand that, the fix is rather obvious:

This will be accepted (and properly "boxed") by the MVC default model binder, without the need to implement a custom model binder and/or TypeConverter manually.

Unfortunately, there's not an easy way to achieve the same result using the standard  HttpUtility.ParseQueryString()  and the UriExtension.ParseQueryString()  methods, meaning that we cannot properly handle these complex query strings outside one of our standard request-routing cycles, where we can use the powerful property-binding feature provided by the MVC framework.

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.