CSS Friendly Control Adapters now available on NuGet

Back in the days of Web Forms, there were server controls, and they generated rather CSS-unfriendly HTML. So, Microsoft got someone (Russ Helfand) to write adapters that changed their rendering to be more CSS-friendly: the “CSS Friendly Control Adapters” were born.

A little less farther back, in 2007, I tried convincing some people at Microsoft to let the community continue development of these adapters, and they agreed. The CSSFriendly CodePlex project was born, and a bunch of bugs and some new features were added.

A lot has changed since then, but the adapters still have use today for people stuck on .Net 2.0 (they’re in the top 200 most downloaded CodePlex projects, and their forums still see activity). To facilitate those who still use CSSFriendly, I’ve added the library package to NuGet.

How to use the CSSFriendly NuGet package

cssfriendly-nuget-packageIn four easy steps (three if you already have NuGet).

  1. First, you need Visual Studio 2010 and NuGet. (If you’re new to NuGet, read the getting started documentation.)
  2. Next, right-click the References folder and choose Add Library Package Reference.
  3. In the Add Library Package Reference window, search for “cssfriendly.”
  4. When you see the CSSFriendly package, click the Install button.

After it installs, the following is added to your project:

  • The CSSFriendly library reference
  • The CSSFriendlyAdapters.browser file in the App_Browsers folder

At that point, you’re ready to go!

The full source of the CSSFriendly library is still available at CodePlex: http://cssfriendly.codeplex.com. Downloads there include sample code and walkthroughs.

Enjoy, and let me know if you have any issues!

Beer and Taxes

The following has been circulated around for a long time. It just resurfaced to me, and I wanted to share it! I wish I knew who to credit it to. 🙁

Suppose that every day, ten men go out for beer and the bill for all ten comes to $100.
If they paid their bill the way we pay our taxes, it would go something like this…

The first four men (the poorest) would pay nothing
The fifth would pay $1
The sixth would pay $3
The seventh would pay $7
The eighth would pay $12
The ninth would pay $18
The tenth man (the richest) would pay $59

So, that’s what they decided to do.

The ten men drank in the bar every day and seemed quite happy with the arrangement, until one day, the owner threw them a curve ball. “Since you are all such good customers,” he said, “I’m going to reduce the cost of your daily beer by $20”. Drinks for the ten men would now cost just $80.

The group still wanted to pay their bill the way we pay our taxes. So the first four men were unaffected. They would still drink for free. But what about the other six men ? How could they divide the $20 windfall so that everyone would get his fair share?

They realized that $20 divided by six is $3.33. But if they subtracted that from everybody’s share, then the fifth man and the sixth man would each end up being paid to drink his beer.

So, the bar owner suggested that it would be fair to reduce each man’s bill by a higher percentage the poorer he was, to follow the principle of the tax system they had been using, and he proceeded to work out the amounts he suggested that each should now pay.

And so the fifth man, like the first four, now paid nothing (100% saving).
The sixth now paid $2 instead of $3 (33% saving).
The seventh now paid $5 instead of $7 (28% saving).
The eighth now paid $9 instead of $12 (25% saving).
The ninth now paid $14 instead of $18 (22% saving).
The tenth now paid $49 instead of $59 (16% saving).

Each of the six was better off than before. And the first four continued to drink for free. But, once outside the bar, the men began to compare their savings.

“I only got a dollar out of the $20 saving,” declared the sixth man. He pointed to the tenth man,”but he got $10!”

“Yeah, that’s right,” exclaimed the fifth man. “I only saved a dollar too. It’s unfair that he got ten times more benefit than me!”

“That’s true!” shouted the seventh man. “Why should he get $10 back, when I got only $2? The wealthy get all the breaks!”

“Wait a minute,” yelled the first four men in unison, “we didn’t get anything at all. This new tax system exploits the poor!”

The nine men surrounded the tenth and beat him up.

The next night the tenth man didn’t show up for drinks so the nine sat down and had their beers without him. But when it came time to pay the bill, they discovered something important. They didn’t have enough money between all of them for even half of the bill!

Insufficient pagefile size can cause obscure memory errors

Today, a user reported an issue connecting to a very old CRM application. I logged in to the system myself and saw no error. Since I’m not happy with self-healing issues, I went digging into the event log on the server.

For the past five days, there have been over 15,000 entries added to the System event log with event ID 333: “An I/O operation initiated by the Registry failed unrecoverably. The Registry could not read in, or write out, or flush, one of the files that contain the system’s image of the Registry.” That doesn’t sound good.

My first stop for analyzing event log errors is eventid.net. The feedback on their site pointed me to a few possibilities.

  • The /3GB switch on a system with 2GB or less of memory.
  • Symantec AntiVirus (which is a potential culprit to every system problem, apparently).
  • Insufficient Non Paged Memory or Paged Pool Memory.
  • Disk or I/O subsystem errors.
  • Overaggressive SQL Server memory usage or I/O affinity.

I checked the server’s memory capacity: 3GB. I checked memory usage in Task Manager: about the same. I checked the page file size, and saw the following (note the highlighted sections).

Ouch! Microsoft has a nice knowledge base article, affectionately titled, RAM, Virtual Memory, Pagefile, and all that stuff, which suggests, as a baseline recommendation, that a pagefile should equal “1.5 times the amount of RAM that is in the computer.” As always, your mileage may vary, but generally speaking, the recommendation is sound. Or, you can just click the “System managed size” option, and forget about it altogether.

The lesson here: check your pagefile settings when setting up a computer, and always revisit them whenever the amount of physical RAM changes.

A practical definition of C# constructors

What’s the textbook definition of a constructor in C#? According to Microsoft (emphasis added):

Whenever a class or struct is created, its constructor is called. A class or struct may have multiple constructors that take different arguments. Constructors enable the programmer to set default values, limit instantiation, and write code that is flexible and easy to read.

That’s not a great definition, but it tells us some important things:

  • There can be many constructors.
  • Constructors may or may not have parameters.
  • Constructors should be used to:
    • set default values,
    • perform limited initialization, and
    • be simple.

In other words, constructors should do as little as possible.

Constructors should:

  • initialize fields and properties
  • check the runtime configuration and environment
  • fail if the object can not be set up properly
  • be consistent, in therms of logic (when using multiple constructors)
  • be thread-safe

Constructors should not:

  • invoke complex business logic (example)
  • use out parameters (example)
  • accept arrays, except as params (use collection types instead)

I’m sure there is more, but those are my guidelines.

Tip: Don’t plagiarize when answering technical interview questions

I’ve been trying to find a SQL programmer/DBA to hire for nearly two months. Each qualified resume I receive gets the same technical screening email with four SQL-related questions. They are not difficult, and most mid-level candidates would be able to answer them in their own words.

“Using someone else’s words isn’t going to get you a job, or help you keep a job if you get it.”

The tip here is to always respond to a technical screening email in your own words. We all know that there are answers to every question on the internet, and we all use the internet as a resource to help solve our problems. This is fine. But when someone sends you an email with technical questions, they want to hear the responses in your own words. It’s OK to provide references to web sites, or quotes/snippets — this shows you know how to do research. But don’t pass off the whole response as your own.

In other words: don’t plagiarize.

Recently, I received a response to one of these emails which had inconsistent use of language, fonts, and font sizes. This raised my copy/paste alarm. So, I did, apparently, the same thing the prospective candidate did: I used Google.

One of the questions is related to identifying performance bottlenecks. The response from the candidate included this paragraph.

Performance Bottlenecks can be detected by using monitors. These monitors might be application server monitors, web server monitors, database server monitors and network monitors. They help in finding out the troubled area in our scenario which causes increased response time. The measurements made are usually performance response time, throughput, hits/sec, network delay graphs, etc.

I searched Google for the first sentence: “Performance Bottlenecks can be detected by using monitors.” The first hit was for a page on the web site GlobalGuideLine. The entire paragraph was copied from that page.

A second question in my screening email is related to storing BLOBs in the database. Part of the response I received read like something out of a technical manual:

In SQL Server, BLOBs can be standard FILESTREAM varbinary(max) data  that store the data in the file system. The size and use of the data determines whether you should use database storage or file system storage. If the following conditions are true, you should consider using FILESTREAM.

Googling the first phrase, “In SQL Server, BLOBs can be standard FILESTREAM”, proved my suspicion: the text is copied verbatim from the Microsoft TechNet article on the SQL FILESTREAM feature.

Needless to say, this candidate isn’t getting the job. Using someone else’s words isn’t going to get you a job, or help you keep a job if you get it. If you’re not qualified, don’t apply. If you can’t answer a question, say you can’t. Don’t pretend. Someone will find out, and it’ll only be worse when they do.

For more resume and interview tips (and experiences), read my blog post Interview and resume tips (and horror stories).

On Snow Removal and Garbage Collection

(Cross-posted on the Staten Island Libertarian Party web site.)

Like most people, I struggled to get around after the snow storm hit. On Monday Dec 27, I checked the MTA web site, which said “Good Service” for all express bus routes. Walking to the bus stop (Arden Ave & Drumgoole Rd), I saw one bus, stuck at the intersection, unable to get up the hill at Arden Ave. I then walked to the train station. The platform was nicely shoveled, and the waiting area was open, and there were signs that a train came by at some point (the rails themselves had little snow on them). No sign was posted about services (or lack thereof). After about an hour, myself and other people waiting started to give up. One person, after repeated attempts, got through to someone at the MTA, who said service wasn’t running at all, and they have no idea when it will be running. I stopped at a local deli (which of course was open), bought a coffee and egg sandwich, and walked back home.

trash.jpg

The amount of work to deal with a significant snowfall is tremendous. Staten Island was reported to get between 18 and 29 inches (varying reports I’ve gotten from different news sources). A news report stated that “every inch of snow costs $1 million to remove”. Keeping trains and buses moving, and streets clear, is a lot of work for a lot of people.

It took two to three days, but things started to return to normal, thanks in part to hard-working public sector workers and hard-working residents (like me, who dug a trench through the hard-packed snow at the end of my block so the snow melt can work its way towards a sewer and not create street and sidewalk flooding). At least, MOST things returned to normal.

Garbage pickup has been suspended since December 25 (the Christmas holiday), and has not resumed until January 3 — a span of NINE days, including two major holidays. I can understand the difficulty in cleaning up snow AND picking up garbage, especially when the same group of people do both. Recycling, however, is not resuming today. The Dept. of Sanitation can not give an estimate as to when recycling pickup will resume.

My garbage pickup days are Wednesday and Saturday, with Saturday being the recycle day. So, assuming my garbage pickup resumes on Wednesday of this week, I will have gone 14 days without garbage pickup. Assuming my recycling will not be picked up this Saturday (since recycling pickup is suspended until further notice), I will have gone 21 days without recycling pickup.

I called 311 last night to find out what I’m supposed to do with my recycling. A summary of the dialog follows:

Me: “Do I put out the recycling with my normal garbage?” ”
311: “No, you still have to recycle.”
Me: “But no one is coming to pick up the recycling.”
311: “Correct, you can’t put it out with the regular garbage. You still have to recycle.”
Me: “So where am I supposed to put three weeks worth of recycling?”

311: “I don’t know.”

In the week since the snowstorm hit, I have seen plenty of private garbage companies and carting companies hauling commercial trash. They do this because (1) they get paid to do it, and (2) people who hire them get fined if they don’t do it. There’s an incentive to pick up the trash — as there should be; keeping trash off the streets is important.

Also in the past week, I have seen garbage trucks driving up and down streets of Staten Island — with a plow affixed to the front. Is there any reason why these trucks can’t also pick up garbage? They’re already going down the street, aren’t they? Even more perplexing was the garbage truck (with plow) driving in my neighborhood, with a salt truck (with plow) directly behind it. Why do you need to send a garbage truck with a plow to escort a salt truck with a plow? Can’t the garbage truck go to another block that needs plowing — or, better yet, pick up garbage?

The reason why private carting can do its job where others can’t is that there is no incentive for the Department of Sanitation to pick up trash. They don’t get fined if they don’t do it; in fact, if you put your garbage out and they don’t pick it up, and you leave it at the curb, they’ll fine YOU for leaving garbage out. They can get around to it when they get around to it, because they know the residents can’t fire them for a job poorly done.

Which is why I want out. I no longer need the services of the Department of Sanitation. I will take care of my own garbage. I’ll find a company to take it. Maybe I’ll have to transport it to them, or maybe they’ll transport it to me. In fact, one of my neighbors expressed interest in the same. So we’ll hire a company to pick up the trash on our block. I’ll take the money spent off my NYC tax bill, since I no longer use those city services. The Dept of Sanitation can now focus on keeping the city street clean (the street I pay taxes to maintain), but they don’t have to stop at my house any more — or perhaps, on my block. Maybe I’ll get two blocks, or heck, maybe my entire neighborhood to join me. I’m sure some private companies would love the opportunity to take residential garbage for a fee, and the competition would be welcome.

Does this sound crazy? It shouldn’t. Earlier in 2010, Deputy Mayor Stephen Goldsmith said he wouldn’t rule out fees for residential garbage pickup. Prior to 1957, the city picked up commercial garbage; things changed in 1957 when the city opted out of that business (much to the happiness of organized crime). Crafty ways to handle residential garbage is already happening in other places (Toronto, New Jersey).

It should happen here, too.

Create your own .pfx file for ClickOnce

Today, I needed a PFX (public key file) to sign a ClickOnce deployment. I spent a fair amount of time trying to figure this out, so I figured I’d share it!

There were plenty of suggested solutions out there, but the best one was from MSDN blogger Maxime Lamure.

In short, do the following, replacing MyCert with the certificate file name (without extension), MyName with the name you want on the certificate (your name, or a company name), and password with the PFX file password.

  1. Open a Visual Studio Command Prompt. If using Windows Vista or Windows 7, be sure to run as Administrator.
  2. Create your certificate (.cer) file by typing: makecert -sv MyCert.pvk -n "CN=MyName" MyCert.cer
  3. Create your public key (.pfx) file by typing: pvk2pfx -pvk MyCert.pvk -spc MyCert.cer -pfx MyCert.pfx -po password

At the end, you’ll have your very own certificate file and public key!

The cost of mandating rear-view cameras on cars

(Cross-posted on the Staten Island Libertarian Party web site.)

This morning, I read a news headline from the LA Times which read, “Rear-view cameras on cars could become mandatory.” An excerpt follows.

The federal government wants automakers to install back-up cameras in all new vehicles starting in late 2014.

Rear-view camera on a car, courtesy of Motor Trend

The plan, announced Friday, received a strong endorsement from insurance industry and other analysts and is likely to get some level of support from car manufacturers.

Of course car manufacturers will support it; it brings in significant revenue. The same article states, “The rear-view camera system adds about $400 to the price of a Ford.”

As per the Bureau of Transportation Statistics, new car sales have averaged around 7.5 million per year for the past ten years. 7.5 million cars at $400 a pop is an additional $3 billion a year. Granted, technology will reduce the cost of implementation, but we’re still looking at lots of money here.

And what do we get for our money? The LA Times article also states, “The National Highway Traffic Safety Administration estimates that, on average, 292 fatalities and 18,000 injuries occur each year as a result of back-over crashes.” That’s $164,000 per fatality or injury (assuming the $3 billion cost.) Or, $3 million per fatality and $118,000 per injury. Seems expensive to me. Couldn’t we install a device on cars which create an audible beeping sound when the car is in reverse? After all, it’s on most large trucks, specifically to mitigate the same problem (look out, a big vehicle is backing up). I’d imagine such a device would be much cheaper than $400 per car, and would likely have a similar effect on reducing injuries and accidents while moving in reverse.

Want a more effective solution? Tell your lawmakers to legalize a driver’s side mirror which eliminates blind spots (source: Scientific American). Yes, such a device has been patented since 1994, which, according to the patent, would help eliminate up to “4 percent of vehicular accidents in 1994″ caused by merges and lane changes. It’s illegal because “current federal safety standards for motor vehicles require driver’s side mirrors to be of ‘unit magnification’” — in other words, flat. Sure, it won’t solve the rear-view problem, but maybe it would solve a bigger problem — at a lower cost.

More government-inspired inefficiency. Let’s hope this one dies before it becomes law.

MVC model validation with Castle Validator

The ASP.Net MVC framework comes with built-in model validation using the Data Annotation validators. Unfortunately, the Data Annotations aren’t as robust as other validation libraries, such as the Castle Validators.

Implementing a custom model validator (for server-side validation — client-side validation requires more than is covered in this post), you need to write an implementation of the ModelValidator and ModelValidatorProvider classes that support the Castle Validators.

An example of how to do this follows. Though it hasn’t been fully tested, it worked for a handful of situations I experimented with. Use this as a starting point for your own server-side model validator implementation. Continue reading

Installing and configuring memcached and PHP on Windows

After upgrading the CSFBL forums to vBulletin 4.0, I noticed that performance was slightly worse than in the previous version. A little searching revealed that vBulletin supports memcached (an in-memory distributed caching system). Since I’ve got RAM to spare, I figured this is worth a shot.

Unfortunately, getting memcached running on the server (Windows Server 2008 R2 64-bit) took a few tricks, and getting memached running through IIS/PHP was another. To help other people through the same process (and to remind myself in the future), I’ll share the installation and configuration steps that worked for me below.

Downloading and configuring memcached

The official distributions of memcached are written for Linux systems, so the first task is finding Windows binaries. The memcached project site, fortunately, has links to Windows binaries, which are hosted by NorthScale. Both 32-bit and 64-bit versions are available.

(Note that NorthScale also offers their own free distribution of memcached, but I was unable to get this to run on my system.)

Versions of memcached prior to 1.4.5 supported a command-line option that would register memcached as a Windows service (as in memcached -d install), but this option was removed in version 1.4.5. The simple alternative is to schedule memcached.exe to run using the Task Scheduler service (Windows 2008/Vista/7).

You can create a task to run memcached on system startup using the following command line:

schtasks /create /sc onstart /tn memcached /tr "'c:\dev\utils\memcached-amd64\memcached.exe' -m 128"

Note the -m 128 argument; this tells memcached to use up to 128MB of RAM. There are other command line arguments available; most useful aside from -m are -l (to specify what IP addresses to bind to) and -vv (to add verbose logging to the console, useful for testing).

Integrating memcached with PHP

In order for PHP to use memcached, you must download the PHP memcached library and add it as an extension to PHP.

PHP extensions can be downloaded from http://downloads.php.net/pierre. Many different extensions are in here; the one I used was php_memcache-5.2-nts-Win32-vc6-x86-20090408.zip. This extension matches two key requirements:

Getting the right version of the extension is important; download the thread-safe version, or the PHP 5.3 version, and it simply won’t work.

Once downloaded, take the php_memcache.dll and put it in the ext folder in your PHP directory (for me, c:\Program Files (x86)\PHP\ext). Then, open the php.ini file (in your PHP directory) and add the following line to the end:

extension=php_memcache.dll

Restart IIS (from the command line, type iisreset), and if you did everything right, memcached should now be available to PHP. If you want to check, you can create a phpinfo page; if php_memcache is listed in the output, the extension is registered correctly.

Other links

To find out more about PHP, memcached, and Windows, check out the following links.