ConvertCsvToList

I create a gist for a helper funtion I used recently to convert a CSV file’s contents to a typed list:

private IList<T> ConvertCsvToList<T>(IList<string> csv, string[] header) {
    var list = new List<T>();
    foreach (var row in csv) {
        var columns = row.Split(',');
        T obj = (T)Activator.CreateInstance(typeof(T));
 
        for (int i = 0; i < columns.Length; i++) {
            var h = Regex.Match(header[i].Replace("@", "_"), 
                @"(?<="")(?:\\.|[^""\\])*(?="")").Value;
            var c = Regex.Match(columns[i], 
                @"(?<="")(?:\\.|[^""\\])*(?="")").Value;
            var prop = typeof(Em.Schools.Data.Domain.Match).GetProperty(h);
            if (prop.PropertyType == typeof(int)) {
                prop.SetValue(obj, Convert.ToInt32(c), null);
            } else {
                prop.SetValue(obj, c, null);
            }
        }
 
        list.Add(obj);
    }
 
    return list;
}

EF and “dynamic” data

We use EF for our e-commerce website, and we have the need to get some data out in the form of reports. Ideally I’d like to be able to basically write up a report query and have the data come out on the other side. However, with EF it isn’t necessarily that simple.

I really don’t want to have to go through all the ceremony of creating models, mapping classes, services, etc. I’d like to keep it pretty simple with a service that can give me back the data I want, then I can use it in a Google Chart or a jQuery datatable or something on the client side. I want the server-side to be basic, and then I can focus on the client-side to give a rich report experience.

I did a quick search and came up with a couple of interesting options. The first is a way to dynamically query views. It sounds very interesting, but it looks like it isn’t quite what I am looking for. The post leaves things a little open-ended, but it looks like the views he is querying already have all the strongly-typed stuff needed and the code just performs dynamic queries against those static objects. I could be wrong though as there is not concrete example of how it is used, just the theory behind all the dynamic wackiness going on.

The next option looks a little more like what I am looking for – it returns a dynamic object using SqlQuery. The code in the post is a little verbose for my taste, but a commenter converted the code into an extension, and I like that idea a lot better. I put his code into a gist.

After looking into the options, I think that maybe the notion that I have to stick with EF is just holding me back. I am very familiar with Massive and have used it and enjoy using it. It is a single class file, and maybe it is just the thing I need to get this report data out of my database easily – which is the idea behind Massive!

Recent gists

I have saved a couple of code snippets lately and just wanted to add them to the blog too. This one enables “focus out” unobtrusive validation. I use this in a couple of forms on the site. Part of this gist also has a little code where I was messing around with “remote” validation to get it to work with the focus out validation – of course, I wasn’t thinking, just geeking out. The remote stuff is already baked in to jquery validation and I already had code to handle the focus out portion, so it wasn’t really worth the time, but I didn’t spend much on it. Anyway, the code:

window.Em = window.Em || {};

Em = {
    setFocusOutValidation: function (form) {
        var s = $.data(form, "validator").settings;
        s.onfocusout = function (element) {
            if ($(element).val().length > 0) {
                $(element).valid();
            }
        };
        s.showErrors = function (map, list) {
            this.defaultShowErrors();
            if (list && list.length > 0) {
                for (prop in map) {
                    $("#" + prop).focus();
                }
            }
            Em.displayValidationSummaryErrors(list);
        };
        return s;
    },
    displayValidationSummaryErrors: function (list) {
        $("[data-valmsg-summary]")
            .removeClass("validation-summary-valid")
            .addClass("validation-summary-errors");
        $("[data-valmsg-summary] ul").html("");
        $.each(list, function (idx, data) {
            $("[data-valmsg-summary] ul").append($("<li></li>")
                .html(data.message));
        });
    }
}

The focus out validation will check if the field is valid (also remotely) and if not, the focus will stay on the invalid field. Sometimes it can get a little wonky, but for the most part it works well. Typically when it doesn’t seem to “work” it is because the validation is setup backwards, like comparing a “new password” to the “confirm password”, rather than the other way around.

Gist

The next gist is a Telerik MVC grid extension I started messing with to handle filtering. Turns out I was making it harder than necessary, and there was already an extension method in the NopCommerce codebase. Oh well, here it is anyway:

public static IList<T> ApplyFilter<T>(this IList<T> list, 
                                      FilterDescriptor filter) {
 
    // We wont allow filtering on anything but string type properties
    if (filter.MemberType != typeof(string)) 
        throw new ArgumentException(@"Filtering is only allowed 
            for properties with a type of 'string'.");
 
    var value = filter.Value.ToString();
    switch (filter.Operator) {
        case FilterOperator.IsEqualTo:
            list = list.Where(x => {
                var propertyValue = x.GetType()
                    .GetProperty(filter.Member)
                    .GetValue(x, null);
                return String.Equals((string)propertyValue, value, 
                    StringComparison.InvariantCultureIgnoreCase);
            }).ToList();
            break;
 
        case FilterOperator.IsNotEqualTo:
            list = list.Where(x => {
                var propertyValue = x.GetType()
                    .GetProperty(filter.Member).GetValue(x, null);
                return String.Equals((string)propertyValue, value, 
                    StringComparison.InvariantCultureIgnoreCase) == false;
            }).ToList();
            break;
 
        case FilterOperator.StartsWith:
            list = list.Where(x => {
                var propertyValue = x.GetType()
                    .GetProperty(filter.Member).GetValue(x, null);
                return ((string)propertyValue).StartsWith(value, 
                    StringComparison.InvariantCultureIgnoreCase);
            }).ToList();
            break;
 
        case FilterOperator.Contains:
            list = list.Where(x => {
                var propertyValue = x.GetType()
                    .GetProperty(filter.Member).GetValue(x, null);
                return ((string)propertyValue).IndexOf(value, 
                    StringComparison.InvariantCultureIgnoreCase) > -1;
            }).ToList();
            break;
 
        case FilterOperator.EndsWith:
            list = list.Where(x => {
                var propertyValue = x.GetType()
                    .GetProperty(filter.Member).GetValue(x, null);
                return ((string)propertyValue).EndsWith(value, 
                    StringComparison.InvariantCultureIgnoreCase);
            }).ToList();
            break;
    }
 
    return list;
}

Gist

The last one is just a little quickie example of how to select data attributes with jQuery:

var d = $("input[data-toggle-class]");
$.each(d, function (idx, data) {
    console.log(idx, data);
});

Gist

I was originally looking for a way to select a wildcard in the data attribute, but I couldn’t get it working. Anyway, this works fine – though I did not actually end up using it. 🙂