Convert a Value to Nullable

I’ve decided to start a new series-like set of articles on highly reusable code snippets. I write a lot of these types of snippets and figure it’s time to share. Kicking off will be the ConvertToNullable function.

Background

I despise boilerplate code in general, but I really hate writing the same code over and over to check if a variable equals some “default” value and acting on that case. That’s why I wrote SafeDataReader (article to come) years ago. SafeDataReader is constructed with a DbDataReader and adds a ton of new Get method that let you easily and safely access fields on the underlying data reader with strong typing.

One of the key benefits of SafeDataReader is that every Get method has an override for supplying a default value. If you use this version of a method, it will return your default value if the field is null (DBNull.Value).

Unfortunately, I wrote SafeDataReader before the much needed Nullable type was introduced to .NET. I also have not taken the time to go back and update it to support nullables. That leads us to the “dilemma” behind today’s code snippet.

The Problem

Have you ever written something like the following?

DateTime? someDate;
DateTime someTemporaryDate = GetSomeDate();
if (someTemporaryDate == DateTime.MinValue) {
  someDate = null;
} else {
  someDate = someTemporaryDate;
}

The GetSomeDate function may be legacy code, but it only returns DateTime (or another value type). However, you write code for the new millennium and want to use nullables for a clearer intent of the unknown value. Regardless, this type of code block is a PITA that bleeds unreadability.

Going back to my SafeDataReader example, here is some code that is nice and tidy until the DateTime value needs converting to a Nullable<DateTime>.

var setting = new Setting {
  Title = reader.GetString("Title"),
  Quantity = reader.GetInt32("Quantity", 1),
  BeginDate = reader.GetDateTime("BeginDate"),
  EndDate = (reader.IsDBNull("EndDate")
      ? (DateTime?)null
      : reader.GetDateTime("EndDate"))
};

Ugh! I hate that bit with the EndDate. Since Setting.EndDate is a nullable DateTime, I have to jump through ugly hoops to handle a null just because my GetDateTime method doesn’t yet support nullables.

The Reusable Solution

Nothing beats a generic reusable solution to such a problem. Let’s see it!

protected static T? ConvertToNullable<T>(T value, T defaultValue)
  where T : struct {
  if (value.Equals(defaultValue)) {
    return null;
  }
  return value;
}

protected static T? ConvertToNullable<T>(T value) where T : struct {
  return ConvertToNullable(value, default(T));
}

Now, we have something that will clean-up those previous examples.

DateTime? someDate = ConvertToNullable(GetSomeDate());
var setting = new Setting {
  Title = reader.GetString("Title"),
  Quantity = reader.GetInt32("Quantity", 1),
  BeginDate = reader.GetDateTime("BeginDate"),
  EndDate = ConvertToNullable((reader.GetDateTime("EndDate"))
};

That is much better! Enjoy!

SecuritySwitch Grows Up on Google Code

Edit: Due to a trademark infringement, this open source project will now be named SecuritySwitch. What a huge PITA it was to migrate to a new project on Google Code! Since you cannot rename a project, I had to create a new one and move everything over to it. I so enjoyed blowing 2 hours of my day off on Good Friday.

I recently posted about an update to my WebPageSecurity module project to the newly named SecuritySwitch. One of the best ways to ramp up coding on the project again is to get it into a public code repository.

Get with Git?

I thought about using Git on GitHub, but I want to get moving on this and that would not be the case if I had to fumble through learning Git now. Although, I do really like the concept of a distributed version control system (DVCS). Instead, I will stick with Subversion (SVN) for now.

Google Code

That lands the project in the capable arms of Google Code, which I find to be a very nice new home for SecuritySwitch. I will likely have a dedicated page here on GeekFreeq for SecuritySwitch that refers visitors to the project on Google Code, and/or I will just pipe updates from the project site here via RSS.

Anyway, this is the first stage of a “grown-up” SecuritySwitch.

WebPageSecurity becomes SecuritySwitch

Edit: Due to a trademark infringement, this open source project will now be named SecuritySwitch. Feel free to read the comment posted by the holder of the trademark on the name I originally planned to use. It was a polite enough message. I think there may be ground for me to stand on with the first name, but I don’t care to go to court over the name of a project that is free for anyone to download.

After a bit of a struggle supporting my WebPageSecurity module on Code Project, I’ve decided to put some quality effort into the project in the very near future. One of the first things that needed attention was the name.

What’s in a Name?

Could I have named it something more generic all those years ago? Perhaps, but not likely. After a few minutes of running through some of the key nouns and verbs that describe the project’s purpose, it will now be known as SecuritySwitch.

Educational Value vs. Quality Functionality

Another change to the project will be the maintenance of the dual source code languages. Since I originally started the module, a distinct project for C# and VB.NET have been maintained. While this was great for the educational aspect of the article and accompanying code, it is not ideal for a quality “product”.

After some consideration, I decided to drop the VB.NET version of the source code in favor of a single project written in C#. An immediate benefit to the community of this decision is faster releases.

What’s Next?

All of this change should be balanced with something to make it all worth while. I intend on stopping development on the 2.x version of the module for .NET 1.1 where it is now. Of course, I’ll fix any bugs, but no new features will likely be added. Version 3.x for .NET 2.0 will continue until version 4.0. That’s when I will add some of the new features in the queue and enable full support for ASP.NET MVC as well.

Keep checking back for more progress on this project.

ASP.NET “Remember Me” Option with Forms Authentication Not Working?

ASP.NET Login Control
ASP.NET Login Control

So, you’ve set the timeout value for forms authentication to a fairly large value, yet checking the “remember me” check box on the Login control still does not persist your users’ authentication, even after a fairly short period of inactivity.

<system.web>
    ...
    <authentication mode="Forms">
        <forms timeout="10080"/>
    </authentication>
    ...
</system.web>

Don’t spend hours trying to figure out why this, seemingly, basic functionality doesn’t perform as it should. The solution to this problem is very simple, albeit somewhat obscure.

Continue reading ASP.NET “Remember Me” Option with Forms Authentication Not Working?

Prince of Persia “Combo Specialist” Achievement/Trophy

If you are like many Prince of Persia gamers out there, you have tried tons of different combinations of attack combos in the hopes of finding the right set that will award you that special achievement/trophy; the “Combo Specialist”. The good news is, you do not have to perform all 1,602 possible combos, like the task hint may lead you to believe. You only need to pull off 60 of them. Other guides will tell you 62, 63, or even more, but 60 is the magic number (remember, a combo is actually two or more attacks). I have tested this list at least 10 times with a new user profile each time. There are a few rules to keep in mind when trying to achieve this goal.

  1. A combo cannot kill the enemy. Even the last hit cannot kill your enemy.
  2. A combo cannot be blocked by the enemy. No part of the combo can be blocked for you to succeed.
  3. A combo cannot knock an enemy into a wall or off a ledge. If your combo chain is interrupted by an edge animation, it will not count.
  4. After you successfully complete all 60 combos, you must kill the enemy you are currently fighting before the achievement/trophy is awarded.
A = Acrobatic; G = Gauntlet; M = Magic; S = Sword
  • A,G
  • A,G,A,G
  • A,G,A,M,G
  • A,G,A,M,M
  • A,G,A,M,S
  • A,G,A,S
  • A,M,G
  • A,M,M,G
  • A,M,M,M
  • A,M,M,S
  • A,M,S,G
  • A,M,S,M,G
  • A,M,S,M,M
  • A,M,S,M,S
  • A,M,S,S
  • A,S,S,S
  • G,A
  • G,A,G
  • G,A,M,G
  • G,A,M,M
  • G,A,M,S
  • G,A,S
  • G,G
  • G,M,A
  • G,M,G
  • G,M,M,A
  • G,M,M,G
  • G,M,M,M
  • G,M,M,S
  • G,M,S,A
  • G,M,S,G
  • G,M,S,M,A
  • G,M,S,M,G
  • G,M,S,M,M
  • G,M,S,M,S
  • G,M,S,S
  • G,S
  • M,A
  • M,G
  • M,M,A
  • M,M,G
  • M,M,M
  • M,M,S
  • M,S,A
  • M,S,G
  • M,S,M,A
  • M,S,M,G
  • M,S,M,M
  • M,S,M,S
  • M,S,S
  • S,A
  • S,G
  • S,M
  • S,S,A
  • S,S,G
  • S,S,M
  • S,S,S,A
  • S,S,S,G
  • S,S,S,M
  • S,S,S,S

Want to Know How I Figured It Out?

How do I know that there are 1,602 total combos? How do I know that 60 of them are required for the “Combo Specialist” achievement/trophy? I wrote a software program to figure it out for me!

That’s right. I could not find a definitive list anywhere on the Net. The official game guide does not even list the exact combos necessary to get the award.

You can read about the program that I wrote on CodeProject.com. If you’re just interested in the code that calculates this award, look near the end of the Contents at the beginning of the article. You can see some very cool screenshots of the application too. Hey, while you’re there, vote me a 5 if you like it!

Simpler Robust ASP.NET Providers

I don’t like writing about something that I’m “currently working on” too often. The problem with that is sometimes other things (e.g. life) get in the way of my proposed timelines. All that aside, there are times when the standard SQL web providers are overly complicated for the rest of my database schema. I think it’s great that you can use the same tables for multiple applications. It’s also great that the primary keys for most of the entities are GUIDs, since these are much harder for an unauthorized user to guess.

Sometimes it’s all just too much!

Integration with the Rest of Your Schema

The default implementation of the ASP.NET providers are not ideal for integrating with the rest of your database schema. By that I mean, if you want to include a foreign key to a user’s ID in a table that you’ve created for your application, you’ll have to play by those default rules. Your foreign key will have to be a unique identifier (SQL Server’s GUID data type).

What if I’ve already defined my entire schema and the User ID I had in mind is an integer?

Write Your Own Providers

Something that I truly appreciate with ASP.NET since version 2 are providers. Being able to customize the implementation details of specific pieces of a well-defined machine is empowering. Unfortunately, for the membership, role and profile providers, your data for each will more than likely be interdependent. For example, you cannot use the default SqlMembershipProvider with a custom role provider that does not link to the aspnet_Users table or use a GUID for the User ID when associating roles to users. If you want to change the data type of the primary keys for some entities, you’ll have to write custom providers for all aspects you wish to use in your application.

It’s also not as simple as just changing the data type from a uniqueidentifier to an int. Ideally, the flexibility to configure the providers to use one of your own existing tables in the database would be more robust than hard-coding several table names into the code. What if the provider uses the correct database provider based on the supplied connection string? How about the option to use dynamic SQL or stored procedures?

These would all be very nice features for a set of ASP.NET providers. Of course, I have a real-world example. My host lets me create MySQL databases for my website. They have MySQL 5 installed, which has the ability to create stored procedures (after a bit of a wait). The only trick here is, stored procedures in MySQL 5 are actually stored in the “mysql” database. This can pose a problem for security in a shared hosting environment. Everyone’s stored procedures are in the same “bucket”! It would be great if I could configure my membership and role providers to use MySQL and build dynamic SQL instead of relying on stored procedures.

They’re Coming

That’s the plan. I am currently writing ASP.NET providers that offer all the benefits mentioned above. When will this project be complete? Who knows with my schedule! I can tell you that I have a couple of big websites that I’m working on that will require MySQL as the backing database. They also require membership and roles support. I guess I’ll be finishing the providers in order to complete those websites. ;-)

Web Page Security – New Version

Some of you know me as a friend and code poet. Some know me as the crazy guy trying to get donations for his dad to get him a Wii. Some just know me as “that guy who wrote the web page security module for ASP.NET“. Others don’t know me at all; how did you end up here by the way?

Well, I am finally setting out to write the next version of the web page security module. I have quite a list of features requested by its many users. The fact is, I’ve been wanting to write the new version for nearly 2 years now. I have an idea that will make this thing so much more usable that I’m beginning to doubt its efficiency. So, before I begin putting too much effort into it, I will be running some tests, like a responsible programmer.

I suspect the new method I have in mind will be a bit more CPU-intensive. The problem is, I have no idea how much more CPU I can expect the algorithm to use. I’ll see how my tests go, beginning tonight. If the metrics show an acceptable increase in CPU (I’ll have to decide what is acceptable), I will begin coding the new version this week.

Stay tuned.

Custom Membership and Role Providers

I work for a community college as their webmaster/web programmer and things tend to be very disparate with regards to systems. The student information system speaks its own language and interfaces with its own data. The Active Directory trees are updated manually each semester. The website has several internal and external tools that various users can use to achieve certain goals.

When trying to communicate across these and other involved systems, it can get a bit crazy. The Web tools are my primary concern. They require authorization granularity that just is not offered via our Active Directory (AD) layout. For example, some of those tools have some users that share a similar AD group and other users that do not. In addition, not all users of an existing group should have access to a given tool. Yet specific collections of users needs access to these tools and I am responsible for granting such access.

Continue reading Custom Membership and Role Providers