Archive for January, 2011

Thou Shalt Name Thy Parameter “command”

22 commentsWritten on January 31st, 2011 by
Categories: ASP.NET MVC, Telerik

I'm currently doing a proof of concept with Telerik's ASP.NET MVC Extensions and ran into something that i find rather troubling. I was trying to get the grid to work with custom binding, so i can take care of paging/sorting serverside for AJAX requests. It was pretty easy to set up, but for some reason my controller method which is invoked for the AJAX requests wasn't being passed the relevant sorting information.

The method definition looks like this:

        [GridAction(EnableCustomBinding = true)]
        public ActionResult GetModels(GridCommand gridCommand)

When i go to a different page in the grid, the gridCommand instance contains the relevant paging information (pagesize, current page). The GridCommand type also exposes a SortDescriptors collection which contains all the information you'd need to correctly sort the data you're supposed to return. Except that in my case, the SortDescriptors collection was always empty. I went through the documentation and looked over everything to make sure that i wasn't doing anything stupid, which is always my first assumption. Unfortunately, everything looked alright. I googled and didn't really find anything, until i found a thread on the Telerik support forum where someone else mentioned the exact same problem. Unfortunately, the thread didn't get an answer so that didn't offer any help.

Then i turned to Reflector to check out the code of Telerik's GridAction attribute. I noticed the following code in the constructor of the argument:

public GridActionAttribute()
{
    this.ActionParameterName = "command";
    this.adapterFactory = DI.Current.Resolve<IGridActionResultAdapterFactory>();
}

Cue the "you've gotta be shitting me" response. I went back to my controller method and changed it to this:

        [GridAction(EnableCustomBinding = true)]
        public ActionResult GetModels(GridCommand command)

And suddenly, it worked.

I can't believe i ran into something like this, in the year 2011. This isn't exactly a good first impression that Telerik is leaving on me, and i can only hope that this proof of concept is not going to turn into a Daily WTF discovery.

Walk Out On Sources Of Negativity

4 commentsWritten on January 28th, 2011 by
Categories: life, Opinions, work/career

I'm not a religious or spiritual individual but there is one thing i strongly believe in: if you put out negativity, it will come back to you in one way or another. Similarly, if you have a positive disposition you're more likely to benefit from other people responding positively towards you, though that's obviously never guaranteed. I know that when i walk around pissed off and filled with negativity, nothing good ever happens to me. People stay away from you or don't want to deal with you at all when you give them that "leave me the fuck alone" vibe. But on the other hand, when i feel good about myself or my life, good things just seem to happen. It's at those moments when i meet interesting new people or when new opportunities seem to present themselves out of nowhere.

If you keep that in mind, the question of "what exactly causes me to be negative?" becomes pretty important. What's the source of my negativity? Are there multiple sources? Why am i keeping those sources of negativity in my life? Those are questions you ought to ask yourself regularly. And you have to be prepared for the fact that the true answers could be hard for you to deal with. In the past 2 years, i've seen a few of my closest friends deal with situations where they got out of serious long-term relationships or seemingly fantastic jobs because those situations were hurting them in a way that could no longer be ignored. And in each case, it was a tough decision but it was made nonetheless and i'm very glad to say that none of them regret the decisions that were made. In fact, they're all better off nowadays.

In my case, it was my previous job. I had been there for 8 years and those years consisted of some great times, and some that were pretty bad. Regardless, i had a strong belief in the company and its future and was truly convinced that it was the best place for me to be. But this summer, i guess i started looking at things differently. I just couldn't believe in the future of the company anymore. I was still working on very interesting stuff, but the attraction of that goes away quickly once you realize that whatever cool stuff you're working on will only be used by a handful of people, if that even. Combine that with some seriously conflicting viewpoints on how your career could evolve and i'm sure you can see how that became a huge source of negativity in my life.

And as with any source of negativity, it ends up influencing your life more than you can imagine. I wouldn't go as far as to say that i was depressed, but it did turn me into a bitter and angry individual. So i thought about it for a few weeks, and decided that the best thing for me would be to just get out of there, which isn't as easy as some of you might expect it to be. After 8 years, you kinda have the feeling that you've invested a lot of yourself into it and there are a couple of people who you consider to be more than just 'coworkers'. Nevertheless, the whole situation was making me miserable, which influences a lot more than just those 8 hours a day when you're at work. I didn't just feel bad at work, i felt bad outside of work as well. Because of how bad the whole situation at work made me feel in general.

Fast forward a few months, and things are looking a lot different. I left my job, went independent, found a great gig and it's having a very positive impact on my life for more than just those 8 hours a day. I don't walk around being frustrated and pissed off anymore, and good things are happening to me because of that. If there's one piece of advice of mine that i'd really like you to follow and to remember, then it is the one that i wanted to share with this post: walk out on the sources of negativity in your life, no matter how hard you think it may be because in the end, it will make you a lot happier than you used to be. That doesn't mean that you have to walk around like a happy hippie all the time because it's only human to feel some negativity once in a while. Just don't let it dominate, that's all. And once you realize it does start to dominate, walk out on the cause of it so it can't manifest into something worse.

Prefixing Input Elements Of Partial Views With ASP.NET MVC

14 commentsWritten on January 24th, 2011 by
Categories: ASP.NET MVC

Suppose we have the following set of classes in an ASP.NET MVC project:

    public class NameModel
    {
        [Display(Name = "First name")]
        [Required]
        public string FirstName { get; set; }

        [Display(Name = "Last name")]
        [Required]
        public string LastName { get; set; }
    }

    public class AddressModel
    {
        [Required]
        public string Street { get; set; }

        [Required]
        public int Number { get; set; }

        [Display(Name = "Zip code")]
        [Required]
        public int ZipCode { get; set; }

        [Required]
        public string City { get; set; }
    }

    public class PersonModel
    {
        public PersonModel()
        {
            Name = new NameModel();
            Address = new AddressModel();
        }

        public NameModel Name { get; private set; }

        public AddressModel Address { get; private set; }

        [Required]
        [MustBeValidEmailAddress(ErrorMessage = "Not a valid email")]
        public string Email { get; set; }
    }

An input form for an instance of PersonModel could look like this:

@using (Html.BeginForm("MyPostAction", "MyController", FormMethod.Post))
{
    @Html.ValidationSummary(true)

    <p>
        @Html.LabelFor(model => model.Name.FirstName)<br />
        @Html.TextBoxFor(model => model.Name.FirstName)
        @Html.ValidationMessageFor(model => model.Name.FirstName)
    </p>

    <p>
        @Html.LabelFor(model => model.Name.LastName)<br />
        @Html.TextBoxFor(model => model.Name.LastName)
        @Html.ValidationMessageFor(model => model.Name.LastName)
    </p>
        
    <p>
        @Html.LabelFor(model => model.Address.Street)<br />
        @Html.TextBoxFor(model => model.Address.Street)
        @Html.ValidationMessageFor(model => model.Address.Street)
    </p>

    <p>
        @Html.LabelFor(model => model.Address.Number)<br />
        @Html.TextBoxFor(model => model.Address.Number)
        @Html.ValidationMessageFor(model => model.Address.Number)
    </p>
    
    <p>
        @Html.LabelFor(model => model.Address.City)<br />
        @Html.TextBoxFor(model => model.Address.City)
        @Html.ValidationMessageFor(model => model.Address.City)
    </p>

    <p>
        @Html.LabelFor(model => model.Address.ZipCode)<br />
        @Html.TextBoxFor(model => model.Address.ZipCode)
        @Html.ValidationMessageFor(model => model.Address.ZipCode)
    </p>
                           
    <p>
        @Html.LabelFor(model => model.Email)<br />
        @Html.TextBoxFor(model => model.Email)
        @Html.ValidationMessageFor(model => model.Email)
    </p>
        
    <input type="submit" value="Confirm" />
}

That would produce HTML like this:

<label for="Name_FirstName">First name</label><br />
        <input data-val="true" data-val-required="The First name field is required." id="Name_FirstName" name="Name.FirstName" type="text" value="" />
        <span class="field-validation-valid" data-valmsg-for="Name.FirstName" data-valmsg-replace="true"></span>
    </p>
    <p>
        <label for="Name_LastName">Last name</label><br />
        <input data-val="true" data-val-required="The Last name field is required." id="Name_LastName" name="Name.LastName" type="text" value="" />
        <span class="field-validation-valid" data-valmsg-for="Name.LastName" data-valmsg-replace="true"></span>
    </p>
    <p>
        <label for="Address_Street">Street</label><br />
        <input data-val="true" data-val-required="The Street field is required." id="Address_Street" name="Address.Street" type="text" value="" />
        <span class="field-validation-valid" data-valmsg-for="Address.Street" data-valmsg-replace="true"></span>
    </p>

Which is perfect, because this means we get client-side validation for free, based on the DataAnnotations that we used on our model classes. Also, pay attention to the values of the name attributes for the input elements. For the Name.FirstName property of an instance of PersonModel, the name attribute of the corresponding element is correctly set to "Name.FirstName". This enables the ModelBinder to correctly bind all values of the submitted form to construct a valid instance of PersonModel. So far, so good.

However, considering that we went through the trouble of creating separate NameModel and AddressModel classes, it would make sense that we use Partial Views to render editable fields for instances of NameModel and AddressModel. Our Partial View for the NameModel could look like this:

@model CarShop.Web.Models.NameModel

    <p>
        @Html.LabelFor(model => model.FirstName)<br />
        @Html.TextBoxFor(model => model.FirstName)
        @Html.ValidationMessageFor(model => model.FirstName)
    </p>

    <p>
        @Html.LabelFor(model => model.LastName)<br />
        @Html.TextBoxFor(model => model.LastName)
        @Html.ValidationMessageFor(model => model.LastName)
    </p>

While our Partial View for our AddressModel would look like this:

@model CarShop.Web.Models.AddressModel

    <p>
        @Html.LabelFor(model => model.Street)<br />
        @Html.TextBoxFor(model => model.Street)
        @Html.ValidationMessageFor(model => model.Street)
    </p>

    <p>
        @Html.LabelFor(model => model.Number)<br />
        @Html.TextBoxFor(model => model.Number)
        @Html.ValidationMessageFor(model => model.Number)
    </p>

    <p>
        @Html.LabelFor(model => model.ZipCode)<br />
        @Html.TextBoxFor(model => model.ZipCode)
        @Html.ValidationMessageFor(model => model.ZipCode)
    </p>
    
    <p>
        @Html.LabelFor(model => model.City)<br />
        @Html.TextBoxFor(model => model.City)
        @Html.ValidationMessageFor(model => model.City)
    </p>

We could then modify our original View so it would look like this:

@using (Html.BeginForm("MyPostAction", "MyController", FormMethod.Post))
{
    @Html.ValidationSummary(true)

    @Html.Partial("NamePartial", Model.Name)
    
    @Html.Partial("AddressPartial", Model.Address)    
                     
    <p>
        @Html.LabelFor(model => model.Email)<br />
        @Html.TextBoxFor(model => model.Email)
        @Html.ValidationMessageFor(model => model.Email)
    </p>
        
    <input type="submit" value="Confirm" />
}

Pretty clean huh? Unfortunately, there's a problem. In the generated HTML, the input fields for Name and Address are (obviously) no longer properly prefixed so the Model Binder would not be able to construct a proper PersonModel instance out of the posted values. Basically, we'd have a PersonModel instance where the Name and Address properties would point to instances whose properties would be null, even when the user filled in the values.

So, how do we set the prefix correctly within the Partial Views? We obviously can't hardcode the prefix within the Partial Views, because that would limit their usability to usage within parent Views where the Model indeed has a property of the correct type and with the expected name. We also really want to keep using the TextBoxFor methods in our Partial Views because that's what gives us the DataAnnotations-based client-side validation for free. Ideally, our Partial Views don't know anything about the prefix and we should be able to pass it in from the parent View. And it would also be nice if we could still use the Partial Views as they are, even when no prefix is required. After some searching, i found a pretty clean way to do this.

When we call the Html.Partial method in the parent View, we can pass in a ViewDataDictionary instance to the Partial View, which contains a TemplateInfo object, and that TemplateInfo object happens to have an HtmlFieldPrefix property. It took me a while to find this, but i'm glad i did. Now i can just change the calls to Html.Partial in the Parent View to this:

    @Html.Partial("NamePartial", Model.Name, new ViewDataDictionary 
    { 
        TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Name" } 
    })
    
    @Html.Partial("AddressPartial", Model.Address, new ViewDataDictionary 
    { 
        TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Address" } 
    })    

And in the generated HTML, the input elements for the NameModel and AddressModel properties will be properly prefixed. Now, we've already achieved our goal of keeping the Partial Views of having to know anything about a prefix that they may or may not need to include depending on which parent View is using them. But, as i'm sure you can agree, passing in the ViewDataDictionary with an instance of TemplateInfo with the correct HtmlFieldPrefix is kinda cumbersome, not to mention repetitive and even slightly error-prone. Ideally, we should be able to change our parent View to this:

    @Html.EditorForNameModel(model => model.Name);
                                                 
    @Html.EditorForAddressModel(model => model.Address);

It's actually quite easy to do so. First, we'll need the following helper method:

        private static MvcHtmlString GetPartial<TRootModel, TModelForPartial>(
            HtmlHelper<TRootModel> helper, string partialName, Expression<Func<TRootModel, TModelForPartial>> getter)
        {
            var prefix = ExpressionHelper.GetExpressionText(getter);

            return helper.Partial(partialName, getter.Compile().Invoke(helper.ViewData.Model),
                new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = prefix } });
        }

I know, i know... that code is butt-ugly due to the generics usage but hey, that's C# for ya. It does allow us to create the EditorForNameModel and EditorForAddressModel methods like this:

        public static MvcHtmlString EditorForNameModel<TModel>(
            this HtmlHelper<TModel> helper, Expression<Func<TModel, NameModel>> getter)
        {
            return GetPartial(helper, "NamePartial", getter);
        }

        public static MvcHtmlString EditorForAddressModel<TModel>(
            this HtmlHelper<TModel> helper, Expression<Func<TModel, AddressModel>> getter)
        {
            return GetPartial(helper, "AddressPartial", getter);
        }

And there we go. Our Partial Views are clean and completely reusable. And using them in a parent View is nice and clean as well.

Don’t Be Afraid To Change Your Mind

22 commentsWritten on January 23rd, 2011 by
Categories: life, Opinions, work/career

The ability to reevaluate your position, thoughts or feelings on something is a very valuable asset to posses. There are quite a few people who have issues with this though. How many problems, in any field or situation you can think of, could be avoided if we'd all be able to say "you know what, i was wrong and i no longer feel the same way about it". Or "well, times have changed and my previous position on this no longer makes sense". Yet there are still a lot of people who are afraid to state that they've changed their mind on something they've made strong statements about in the past. I don't know why that is, though i suspect that in most cases it's all about fear of being perceived as weak. After all, if you're smart and strong you're surely quite capable of forming the "right" opinion initially, so there wouldn't be any reason to actually change your mind about it later, right? Right...

An opinion is always formed within a context. There are many things that can influence or form a context, but a lot of them are temporal in nature. Simply put: things change, as do people (to an extent). The reasons behind an opinion of yours are unlikely to remain the same for the rest of your life. Granted, some of them can remain the same, but the majority of them won't. An opinion that was formed within a certain context is thus likely to become invalid sooner or later within the way you look at things.

Obviously, i don't think there's anything wrong with changing your mind about something. It shows that you've given the issue some new thought. An inability to change your mind, even when the context in which the original opinion was formed has changed, shows a few other possibilities. Perhaps you're unable to assess how the situation has changed. Perhaps you don't want to be perceived as weak for changing your position. Or maybe you haven't even gone through the trouble to think about the issue again. Or maybe you have, and you still stand by your opinion. In the latter case, you can at least rationalize why you're sticking to your opinion. In the former 3 cases, you can't and people will only think less of you because of it.

The Inquisitive Coder, Version 2.0

18 commentsWritten on January 22nd, 2011 by
Categories: About The Blog

Lately, i've grown somewhat tired of this blog. Well, i've grown tired with how it looks specifically. But there were some other minor issues that started getting on my nerves. I even started contemplating the possibility of just writing my own blog engine so i'd have full control over everything. Luckily for me, i regained my senses soon enough and decided to stick with WordPress, but to spruce things up a little.

As you can see (unless you're reading this in your RSS reader), i've chosen an entirely new theme for the blog. The previous one wasn't actively supported anymore and it started to bore the hell out of me. This one is pretty different, but i like it. It's clean, simple and i don't think it's being used by any other tech blog :)

Another important change is that i've dropped the regular WordPress commenting system and finally switched to Disqus. There's nothing wrong with WordPress' commenting system but it is pretty basic and as of about 2 weeks ago, the majority of my server load came from filtering spam comments despite the CAPTCHA system i was forcing you to use. Needless to say, the ability to offer a lot more functionality to people who are willing to leave comments without having to bother them with some annoying CAPTCHA system, while at the same time offloading the burden of spam filtering entirely on 3rd party services was a no brainer :)

Also, no more ads. They're gone from the site as well as the RSS feed. Nobody wants to see those anyway and it's not like i need the extra pocket change so there's no reason to keep them around :)