Tigraine

Daniel Hoelbling-Inzko talks about programming

Do the simplest thing you can get away with

So, yesterday I was talking to a customer about a new project I will be developing over the next month or so.
And half way through the project (revamping a legacy system), I was asked if I could insert sorting into a statistical grid view.

I immediately started thinking about using a ASP.NET grid view control with sorting and paging capabilities enabled. But just before I could open my mouth, it hit me: Why in the heck should I do something that stupid?

My customer isn't only good at using Excel, these guys are traders! They probably know better how to do sorting in Excel than I know how to do it in ASP.NET!

So, because this grid was filled through some pretty complex selection criteria, why in the hell wasn't my first idea to simply give them a CSV list with all the data they need and let them do it themselves.

This solution isn't only superior for the customer, it's also much better for me because code you don't write can't break! Excel is giving my customer all the things he otherwise would demand from my application, with added benefits like pie charts and custom functions. Why should I even bother to take on this?

The smartest code is no code at all!

If you can get away without writing code, do it immediately. Every line you write less is one you don't have to care about later.

Filed under net, programmierung

Subnetting is good

Still on the train from Vienna to Klagenfurt, I'm listening to RunAs radio (yeah, I'm running out of DNR episodes) and just listened to the talk about IPv6 and how the big address space can simplify networking by removing the need for subnetting as we know it today.

And, I'm really curious if this is a good thing from a simplicity perspective. I mean, ok maybe my ISP is giving me 4 bits of address space in the future so I don't need my own personal router and subnet, but that would also mean that every computer in my network is directly attached to the Internet making it a necessity to have all machines (ok, that should be standard anyway) run latest and best protection software, having all patches up and being just as secure as my DMZ servers would have been before.

And that's something I don't see happening any time soon. I trust myself to have my laptop and desktop patched and secure, but I simply don't want to waste the time to do so on my father's PC, my brothers etc..
I simply want to rely on that they are somewhat secured through simply not being publicly available through the Internet because my router isn't forwarding any ports to them that could be exploited.

So, although I really think the new network stack in Vista and 2008 is a huge step forward and network performance for me has increased with the use of v6. I still don't think that subnets should go away anytime soon.

Filed under internet, personal

Good design leads to problems

Bad design is in most cases the result of people not knowing better, and while I am constantly struggling to learn more about good architecture design I sometimes feel like: How in the hell can I ever make this work inside of ASP.NET?

I mean, most "good" things like IOC, TDD, information hiding, separation of concerns etc all rely on you having total control over your classes.

But, that's something you can only achieve in ASP.NET by throwing a whole bunch of code at things that would have worked effortless without the "good" stuff.

Best example of this may be simple ASP.NET pages that come with Request, Response and Context objects that cannot be swapped out as easily.
Now your usual course of action to keep your code testable would be to simply put the business code into underlying classes that then get called by the untestable ASP.NET page. But, this now leads to the problem that I can't really use the full power of ASP.NET any more, SqlDataSource has just gotten off limits, because we don't want to expose our data access layer to the application (or at least try to avoid that).

So, because comprehensive data binding just left the building, what did we get for our good design?
We just got the even bigger task at hand to do databinding by hand. And now we are even more in trouble than we were with the untestable app, because now we will find ourselves writing even more code we need to test even more.

You see what I'm getting at? If we would have been using data binding, we could have just relied on working, well tested code (hey that's what Microsoft for!), without the hassle to reinvent the wheel again and being concerned with the wheel's quality.

So, I still can't offer a suitable solution for this dilemma, maybe use object-data-source a lot more? But what about update support? I'll be looking into this topic and when I've come up with something I'll let you know.

Filed under net, programmierung

Snappy Windows Recovery

Do you remember those times when you where reinstalling your OS every two weeks? Those dark Windows 98 times that have thankfully passed away?
I don't shed tears when remembering the days of old, but mainly because Windows doesn't need reinstallation every two weeks any more.

To be honest, back when I was using Windows XP: I was rarely using any restore options, because they hardly ever worked the way I wanted them.
Thankfully the system wasn't as easy to break as the 9x family (love NT for that), but still when something went terribly wrong I was pretty quick in digging up those XP cds and re-doing the system (guess that's what we were used to :)).

So, yesterday I unboxed my sweet new Dell XPS M1330 laptop and immediately started setting it up. Configuring Vista for the first time, getting Office, Windows Live and Visual Studio 2008 on the machine - all that stuff you don't want to be doing too often.
I also immediately downloaded .NET 3.5 SP1 and VS2008 SP1 (both beta), because I really liked some of the new IDE features.

Upon .NET 3.5 SP1 installation things went bad.. I mean, really bad.

Visual Studio didn't start up any more, .NET programs compiled against the 2.0 runtime refused to work any more (my pre-installed Dell Dock application).
I tried the obvious, uninstall SP1, repair 3.5.

Now, when even the setups don't start up any more, you usually flip out your OS Cds and think about reinstalling.

But, I thought, I could give Vista's recovery a try and searched for available recovery points.

image

And tada, there they where. Almost everything I installed added a recovery point to the system and I even had the luxury of choosing to what app I want to restore my system to - great!

10 Minutes after starting the recovery I was up and running again, having absolutely 0 problems! Perfect.
I even reinstalled Visual Studio 2008 and everything works just fine.

So I guess reinstalling Windows is completely out for now. When there are restore options available like this, I don't think I'll be ever reinstalling anything any more.

Oh, and I think I won't try the .NET 3.5 SP1 beta again, let's see when it gets to final. The new additions to the framework are pretty minor, but the updates to the IDE are definitely worth it.

Filed under net, personal

The comfort of not working with real data

I am very fortunate to have been working on many projects that started from scratch, so I never had to deal with pre-existing databases and structures.
Although this fact makes it easier to create a good architecture, you'll find yourself constantly inserting some bogus data into the database to be able to test the application.
And usually you'll wipe your database clean once you're ready for release and forget all about that data.

Don't do that. It won't cost you a thing to export the test data to a SQL and have it handy in case you're ever going back to the application to change something.

Let's say your app was performing great and you now have 2000 users using it. Going back brings forth some problems:

  • User data is subject to privacy laws and cannot be handled freely.
  • Working on the real database is always stupid (remember when you didn't include a WHERE clause to a update statement?)
  • Washing real user data clean of all private information is sometimes quite difficult.
  • Huge amounts of data make detecting errors more difficult.

Privacy laws may be the most important point in the above list I think. If you're working on the real dataset you're in trouble once you want to outsource the development or bring in new people to the team. They'll have to sign a NDA and even under a NDA they could make the mistake of disclosing this information without their knowledge (most NDAs don't pass on liability in such cases, in that case you're now facing two legal problems. Sue your programmer and get sued by privacy advocates).

Not taking such risks is usually the better choice! By using your bogus development database you'll be easily able to verify behavior while having the luxury of being able to freely bring in new members to the team (mind your IP).

Filed under programmierung

Rant: Visual Studio injecting Ids to absolutely everything!

Ha, the weekends almost in and I'm readying myself to get afk for some days.
But not before I've complained about how stupid Visual Studio gets when you're handling ASP.NET Tables!

Whenever something has a runat="server" tag Visual Studio wants to attach an ID to it.
But there is no point to attach IDs to every cell/row in table!

So, if you're writing everything by hand, you don't need to specify the ID attribute, so everything is fine. But once you want to copy&paste that code, Visual Studio will instantly attach IDs to everything (with meaningful names as "Table1, TableRow1" etc..), and that's something I find very annoying when having to create large forms or something like that.

I mean, you have code like this:

<asp:Table runat="server">
    <asp:TableRow runat="server"></asp:TableRow>
</asp:Table>

and once you hit CRTL+V it get's obscured like this:

<asp:Table ID="Table1" runat="server">
    <asp:TableRow ID="TableRow1" runat="server"></asp:TableRow>
</asp:Table>

Now, being a thoughtful developer who likes tidy markup, I'm now going to remove these useless Ids from my code once again.

Oh, and did I mention that this also happens when you cut&paste? Nothing is more annoying than getting IDs injected when you're reordering table rows.

There is merit to the idea when you are copy&pasting real controls that have IDs attached, so you don't accidentally find yourself with multiple controls with the same ID. But when there is no ID attached to the code you're having in the clipboard, Visual Studio shouldn't be putting it in there.

Filed under net, programmierung

Session handling in ASP.NET

Often you need to save data to a user-central location (something like a global variable per user) and you immediately think of the session as the perfect place to store that data.
So you have this just retrieved user-id and you go:

Session["userid"] = userid;

And this works perfectly fine, ASP.NET will take care of the cookie handling etc while you can conveniently read from this field from now on.
But, there is one catch (as always):

Accessing session data is a very error prone process and should never left to the business code itself. Whenever a session times out you'll get NullPointerExceptions cluttered throughout your application (because reading from Session["userid"] will quietly return null if the session isn't there or got lost).
Working directly with the session also robs you of all the type-checking goodness we are all used to from .NET, so you may get some InvalidCastExceptions while accessing your objects too.


And, whenever you call Session["useid"] you're risking spelling mistakes what would lead to completely bogus data.

So, I hope you get my point, working with the session object directly is really nothing you'd want to do over and over again (and therefore risking errors every time).
It's usually much better to centralize this in one spot and test that well.


And centralizing this can be easily done through creating a custom class for this that will not only keep the session object away from you, but also provide you type-safe access to your data.

I suggest starting off with the session data object that we will use to store our data in:

[Serializable()]
public class UserSessionData
{
    public int UserId
    { get; set; }
}

Notice that I've put the Serializable() attribute onto the class so if you want to store the session in a state server or in sql server the CLR knows how to serialize the object and store it.
The whole object is solely responsible for keeping our UserId, nothing more nothing less.

And now we need to store this object in the session, for that purpose we could just incorporate static methods into the class that would retrieve and set the object to the current session.
Because we're working with ASP.NET here we want this UserSessionData to be accessible from within our ASP.NET Webform so it's pretty cool to just subclass Web.UI.Page and use it afterwards as the base class for our Webforms:

public class SessionHandler : System.Web.UI.Page
{
    private const string SESSION_NAME = "UserSession";
    public UserSessionData SessionData
    {
        get
        {
            UserSessionData sessionData = (UserSessionData)Session[SESSION_NAME];
            if (sessionData != null)
                return sessionData;
            else
                throw new Exception("Could not retrieve session state");
        }
        set
        {
            Session[SESSION_NAME] = value;
        }
    }
}

Now we only need to open our code-behind file and change it's superclass from Page to our SessionHandler (that just wraps Page):

public partial class _Default : SessionHandler
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.Title = this.SessionData.UserId.ToString();
    }   
}

Now whenever you need to read the UserId there is this neat property called SessionData that knows all about your user, while you don't need to do any is-null checks any more in your code, that's all handled by the SessionHandler class when accessing the session object :).

Hope this helps!

Filed under net, programmierung

Validation Controls in ASP.NET

So, yesterday I noticed something funny while doing some data-driven ASP.NET programming.

There are those really great Validation controls that really reduce the amount of code you need to write on average input forms.

So, imagine you have quite usual code like this:

<asp:TextBox runat="server" ID="MyTextbox"></asp:TextBox><br />
<asp:RequiredFieldValidator ControlToValidate="MyTextbox" runat="server"><br />
    Textbox shouldn't be empty
</asp:RequiredFieldValidator>

<asp:Button runat="server" Text="Submit" OnClick="Submit_Click" />

This will result in a simple form with a textbox and a submit button. The handler code for the button looks like this:

public void Submit_Click(object sender, EventArgs e)
{
    this.Title = "Hello World";
}

Now, if you click on the button while leaving the textbox blank, you'll see the red message that the field needs to be filled.

If you disable Javascript in your browser, the handler code will get executed without getting validated!

Actually, the validation is done solely on the client if you don't manually check for the Page.isValid property on the Webform.

So, here is the revised handler code:

public void Submit_Click(object sender, EventArgs e)
{
    if (this.IsValid)
    {
        this.Title = "Hello World";
    }
}

This isn't something unknown, MSDN points it out on some occasions. But yet, something you might overlook too easily.

Keep this in mind when working with validator controls, hope this helps!

Filed under net, programmierung

How not to serve customers

I decided some time ago that I don't want to blog about non technical stuff any more.
But it's Sunday and I hope you'll excuse this one.

What happened? The-best-girlfriend-someone-can-imagine™ just returned from a 2 week study trip to Slovenia while I've been holding up here in Klagenfurt. Upon returning I imagined it would be cool to celebrate her return with romantic dinner at a Mexican restaurant here in Klagenfurt.

The restaurant I'm referring to is the Salud that usually serves truly great Mexican food. But while their food truly justifies the somewhat high price, their service is just ridiculous!

I've never seen service like this.
In short it's been a really really unpleasant experience, but what really stood out was that the waitress tried to take away my plate while I was still chewing my last bite!
And then she kept standing there for at last 5 seconds watching my girlfriend chew on her last bite too!

There is nothing I hate more than being interrupted while eating at a restaurant, except for being watched while eating.

So, just to compensate for the useless post, here a list of great places to eat (where I actually liked the service) in Klagenfurt:

  • Chinesischer Garten
    • Very good Chinese food, fast and very polite service. Very reasonable prices (with all you can eat etc)
  • Da Pietro
    • Not the cheapest Italian restaurant you'll find, but the food tastes great. And the waiters there are absolutely the best you'll find in Klagenfurt.
  • Longhorn Saloon: Steakhouse
    • I don't like steak, but most of my friends have agreed that this has to be one of the best places to eat steak in the center of Klagenfurt.

Filed under personal

Custom ASP.NET Membership provider

I've been ranting too much lately, so I guess it's time to get back into coding.

This time around I've been challenged with a new project that involves a legacy database, while my task is to rewrite the ASP.NET application that runs ontop of that database without actually touching the database.

So first: What is ASP.NET Membership?

Simple answer: A great way to build authentication with little to zero coding effort with very cool draggy-droppy developer experience :). You simply drag a Login control to your ASP.NET page and your application just learned how to authenticate and keep the session of users.

To achieve this on a already existing database you simply need to do one thing:

Implement the abstract class MembershipProvider and implement just one method: ValidateUser

public override bool ValidateUser(string username, string password)
{
    if (username == "tigraine" && password == "tigraine")
        return true;
    return false;
}
You see where I'm going here, you basically just need to return true or false given a username and a password. How you do it is entirely up to you as long as you return either true or false.

To make the magic actually work you need to add the new MembershipProvider (i've called it DBMembershipProvider) to your root web.config:

<authentication mode="Forms">
	<forms loginUrl="Login.aspx"></forms>
</authentication>
<membership defaultProvider="DBMembershipProvider">
	<providers>
		<add name="DBMembershipProvider" type="DBMembershipProvider" />
	</providers>
</membership>
The <authentication mode="Forms"> is quite important because it tells asp.net to actually use forms driven authentication instead of windows authentication or microsoft passport. I also defined the loginUrl attribute to tell the app where to redirect anonymous users, but that's optional.

The membership stuff now is important, because here we glue the new provider into our system.

We just add a new provider in the <providers> section and name it conveniently, and most important: we tell .net what type to instantiate.

The defaultProvider property then tells .net what provider to use (if you've got multiple providers to log into your website, eg: Windows and Forms auth)

And, that's it. As long as the ValidateUser method returns true/false, your users can now use a fancy Login form to authenticate and their login session will get stored in a cookie. You can now drag LoginStatus and LoginName controls to your form and watch the goodness work :).

Hey! How do you actually secure something with this?

Yeah, I was so happy with that login working so I almost forgot to do this part. Usually you want to protect some files or directories from unregistered users. This also happens at the web.config level and is quite easy.

In case of a folder, just put a blank web.config in there and add the following directives:

<system.web>
	<authorization>
		<deny users="?"/>
	</authorization>
</system.web>
Now only registered users have access to this directory and you're done.

If you don't want to lock the whole directory but only some files in there you can do this through the verb attribute by either specifying a regex or a filename to be affected by your rule. (You could also use the <allow> tag to add exceptions to your deny tag I think)

Actually, if you look at the MembershipProvider, there's a ton more functionality I just skipped here. But this has been everything I needed to get login and user restriction for my current project, so I thought it's worth sharing how darn easy this actually is. If you want to delve deeper into the topic I'd suggest you either read 4GuyFromRolla or search through MSDN.

Filed under net, programmierung