dinsdag 24 februari 2009

Things I still want to blog about

So, it’s busy, life’s busy, I’m busy. So I want to make a list for myself what to blog about. I’ve got a lot of interests, but I’d like to stay in line with the general topics I’ve written about so far. So, here’s my list for the coming weeks (months?).

  • NHibernate and custom usertypes
    I’ve recently ran into a simple case where this might apply. I’ve got the code, just need the explanation.
  • Storing an unbounded tree structure with NHibernate
    Using modified preorder tree traversal. This seems to be a great way of storing trees, it’s just very clumsy to use.
  • More on moving from SVN to Mercurial
    I’ve already taken Mercurial into my production cycle, but I need to finish my drafts on this!
  • Making yourself known on the web
    It’s what I am doing. I want a good professional presence on the web, as it might help getting credibility in the future.
  • Contributing to OSS series
    In my opinion, one of the best ways of gaining ‘web-cred’. Especially if you pick something that’s going to be the next best thing since sliced bread which is still small enough to make an impact on. Subjects in this series would be something like ‘choosing your pet project’, ‘first steps into contributing’ and something about how documenting/translating is helping too. This series will also mark my experiences so far with contributing to OSS (which I intend to pick up a lot more).
  • Something about IoC containers, notably Unity and Windsor

And some ‘maybes':

  • Selection of a suitable WYSYWIG web editor
    We all need a good one, but there’s a lot of outdated stuff out there. Malformed/deprecated HTML, embedded styles…
  • jQuery fun
    jQuery is fun to use, but I don’t know if there’s enough material for me to write about.

To get myself up to speed, I want to write something at least once a week, as long as I have material to write about. I want to see that hitcounter ticking in real time!

dinsdag 10 februari 2009

jQuery delete link with downlevel support: my version

Phil Haack recently blogged on using jQuery for creating a delete link in ASP.NET MVC which uses ajax when available, while still using conventional form posts when needed. One of the comments was about using the same html link in both cases opposed to changing from a html link to a submit button and vice versa. One advantage of that is that you enable a common case when deleting an item: a confirmation dialog/screen.
It just so happens that I recently implemented a very crude version of this in my pet project.

First off, I’d like to mention that I left out some of the implementation details, as that would cloud the example. Things like anti forgery tokens and such are your own responsibility. Ok, let’s get started.

The HTML rendered looks like this, more or less:

<table class=”gridview”>
<tr>
<th>field1</th>
<th>field2</th>
<th>actions</th>
</tr>
<tr>
<td>fieldvalue1</td>
<td>fieldvalue2</td>
<td><a href=”/MyController/Delete/1” class=”delete-link”>delete</a>
</tr>
</table>


When this renders, it will show a simple grid, with a delete link on the data row. Each additional data row follows the same pattern, obviously. The route on the link leads to the following method on the controller:



[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Delete(int? id)
{
ViewData["id"] = id;
return View();
}


Simple enough, it renders a view called delete.aspx, which will render our confirmation form. I accept a nullable int here, I’ll explain why later on. The view rendered outputs the a form in this fashion:



<form action=”/MyController/Delete/1”>
<input type=”submit” value=”yes I’m sure!” />
</form>


It takes the id for the route from the viewdata, nothing more, nothing less. When submitted, it leads to this method on the controller:



[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id)
{
// delete your entity here, then check if it’s ajax, if not, redirect to your list overview or something
return RedirectToAction(“list”);
}


Now, this is why I accepted a nullable int as an argument for the confirmation form. Because I needed an int on both the post- and the get-action, I wanted two different methods. However, I can’t have two methods on the same class which have the same signature. By changing one of the ints to nullable I have two different methods, with the same name and almost the same signature. Close enough to allow the same route to lead to both methods if needed. By distinguishing on HTTP verbs I won’t get an exception about ambigious routes.



Now, for the jQuery ajax magic, I added a little script to the top of the page, which does little more than add an onclick event to the delete links. It’s not much different from Phil’s code:



$(".gridview .delete").click(function()
{
if(confirm("Are you really sure?"))
{
$.post(this.href);
}
return false;
});


There you have it. When javascript is turned off, the delete link leads to a confirmation page showing a form with a confirmation button. Click the button and the delete function is called, redirecting to the list view after deleting the item. When javascript IS available, a confirm dialog pops up, and it will delete the item when you click ‘Ok’. Now you will have to fill in the blanks, like reloading your list view when an item is deleted or something like that.

vrijdag 6 februari 2009

I couldn’t resist the calling

Ladies and gentlemen, I am now on Twitter. You can find me as tedkees. Feel free to follow me, or just ignore it. That’s fine too.

What made me do it? Well, Scott Hanselman of course!

donderdag 5 februari 2009

Running a business 101: Treat your customer with respect

This post is inspired by a lengthy open letter blog from Ayende about his experiences with a licensing component, interlaced with my own experiences on dealing with my clients. In my day job I regularly have to talk to (potential) clients about their wishes, their problems and overall product satisfaction. So even though I don’t run my own company, I think I do have some experience with dealing with clients now and then.

Communication is the key. Communication is essential for managing your clients. Software development inherently introduces bugs, requirements mismatch and all sorts of other problems. The biggest cause of this is simply that your client doesn’t understand what you do, and vice-versa. In a development project, you should spend a lot of time on getting the intention clear: what’s the problem, and how do we intend to solve it. Notice that I explicitly avoided using the word ‘requirements’, as those (details) can change along the way.

Support doesn’t mean fixing the problem right away. What’s your biggest annoyance when the product is not working like it’s supposed to? Right. You don’t know WHAT is happening, or WHY. When a client comes to you with a problem, try to identify it and acknowledge that the issue has been recorded. Give them a real deadline (don’t fall in the ‘we’ll look at it soon(tm)’ trap!) so they know when to expect information. Also give them an indication on what you intend to have for them at the deadline. Don’t offer help if you can’t follow through!

Some people might argue that there IS NO bad publicity. Although this might hold true for some cases, usually bad publicity will haunt you. Of course you could try to categorize your clients by their influence, but aside from that being at least unethical, it’s also impossible to know how much of your performance with that specific customer will come out. The best thing you can do when something doesn’t work out is diagnose the failure as soon as possible. Don’t drag it out because you hope it ‘will all work out eventually’, because this will usually end up in you needing a massive amount of time (= money) to fix the problems if at all possible, and your client will get more and more annoyed. Even if you eventually produce what they want, the harm is already done. Your relationship with the client will have taken a lot of damage, which may or may not be permanent.

If all else fails, offer a refund. Take your loss, don’t worry too much about the money they gave (or owe) you. If it’s about a product that works out of the box (like Photoshop, Visual Studio), just offer a full refund. When it’s about a development project, try to agree how much you can deliver which they can still use. For instance, if you did a feasibility study, find out if they can reuse it when they take the project elsewhere. If your client can use it, offer it to them for part of the total sum of the project.

I think XHEO (the author of the component Ayende wanted to use) didn’t realize the amount of influence Ayende has in the blogosphere. A lot of people that read his blog are (semi)professional .NET developers which are potential customers. Thanks to his story, they will think twice before choosing XHEO components. That’s what bad manners (or perceived manners) with your customers can cause.

So remember: Treat your customers with respect, and try to help them however you can. If you can’t, try to find an acceptable solution for both so you can put the problems behind you.