I've done a number of talks on Productivity in the past. Lots of folks ask me what my tips are for being productive. I've taken all those tips as well as tips from Kathy Sierra, Stephen Covey, David Allen, The Pomodoro Technique and many more and aggregated them into a system that works well for me. I talk about how to effectively handle large amounts email, sorting your personal data stream, how to conserve your keystrokes, the "one email rule" that you need to be effective

I'm giving this talk in a few places in the coming months like StirTrek in Ohio, DevCon in Russia, and possibly "That Conference" in Wisconsin. If you will be attending one of these events, you might want to wait and see it in person. ;)

There's a few jokes in the beginning of the talk that refer back to some discussion about Gamification and a funny back and forth that Kathy Sierra and I had. If they don't make sense, that's the context.

Of course, feel free to share this post with your friends. I hope it helps them.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

Often folks want to dynamically generate stuff with ASP.NET. The want to dynamically generate PDFs, GIFs, PNGs, CSVs, and lots more. It's easy to do this, but there's a few things to be aware of if you want to keep things as simple and scalable as possible.

You need to think about the whole pipeline as any HTTP request comes in. The goal is to have just the minimum number of things run to do the job effectively and securely, but you also need to think about "who sees the URL and when."

This diagram isn't meant to be exhaustive, but rather give a general sense of when things happen.

Modules can see any request if they are plugged into the pipeline. There are native modules written in C++ and managed modules written in .NET. Managed modules are run anytime a URL ends up being processed by ASP.NET or if "RAMMFAR" is turned on.

RAMMFAR means "runAllManagedModulesForAllRequests" and refers to this optional setting in your web.config.

You want to avoid having this option turned on if your configuration and architecture can handle it. This does exactly what it says. All managed modules will run for all requests. That means *.* folks. PNGs, PDFs, everything including static files ends up getting seen by ASP.NET and the full pipeline. If you can let IIS handle a request before ASP.NET sees it, that's better.

Remember that the key to scaling is to do as little as possible. You can certainly make a foo.aspx in ASP.NET Web Forms page and have it dynamically generate a graphic, but there's some non-zero amount of overhead involved in the creation of the page and its lifecycle. You can make a MyImageController in ASP.NET MVC but there's some overhead in the Routing that chopped up the URL and decided to route it to the Controller. You can create just an HttpHandler or ashx. The result in all these cases is that an image gets generated but if you can get in and get out as fast as you can it'll be better for everyone. You can route the HttpHandler with ASP.NET Routing or plug it into web.config directly.

Works But...Dynamic Images with RAMMFAR and ASP.NET MVC

A customer wrote me who was using ASP.NET Routing (which is an HttpModule) and a custom routing handler to generate images like this:

The benefits of using MVC is that handler is integrated into your routing table. The bad thing is that doing this simple thing requires RAMMFAR to be on. Every module sees every request now so you can generate your graphic. Did you want that side effect? The bold is to make you pay attention, not scare you. But you do need to know what changes you're making that might affect the whole application pipeline.

(As an aside, if you're a big site doing dynamic images, you really should have your images on their own cookieless subdomain in the cloud somewhere with lots of caching, but that's another article).

So routing to an HttpHandler (or an MVC Controller) is an OK solution but it's worth exploring to see if there's an easier way that would involve fewer moving parts. In this case the they really want the file to have the extension *.png rather than *.aspx (page) or *.ashx (handler) as it they believe it affects their image's SEO in Google Image search.

Better: Custom HttpHandlers

Remember that HttpHandlers are targeted to a specific path, file or wildcard and HttpModules are always watching. Why not use an HttpHandler directly and plug it in at the web.config level and set runAllManagedModulesForAllRequests="false"?

Note how I have a * there in part of the URL? Let's try hitting http://localhost:37865/images/handlerproducts/myproductname/default.png. It still works.

This lets us not only completely bypass the managed ASP.NET Routing system but also remove RAMMFAR so fewer modules are involved for other requests. By default, managed modules will only run for requests that ended up mapped to the managed pipeline and that's almost always requests with an extension. You may need to be aware of routing if you have a "greedy route" that might try to get ahold of your URL. You might want an IgnoreRoute. You also need to be aware of modules earlier in the process that have a greedy BeginRequest.

The customer could setup ASP.NET and IIS to route request for *.png to ASP.NET, but why not be as specific as possible so that the minimum number of requests is routed through the managed pipeline? Don't do more work than you need to.

Extentionless URLs support was added in this KB http://support.microsoft.com/kb/980368 and ships with ASP.NET MVC 4. If you have ASP.NET MVC 4, you have Extentionless URLs on your development machine. But your server may not. You may need to install this hotfix, or turn on RAMMFAR. I would rather you install the update than turn on RAMMFAR if you can avoid it. The Run All Modules options is really a wildcard mapping.

Extensionless URLs exists so you can have URLs like /home/about and not /home/about.aspx. It exists to get URLs without extensions to be seen be the managed pipelines while URLs with extensions are not seen any differently. The performance benefits of Extensionless URLs over RAMMFAR are significant.

If you have static files like CSS, JS and PNG files you really want those to be handled by IIS (and HTTP.SYS) for speed. Don't let your static files get mapped to ASP.NET if you can avoid it.

Conclusion

When you're considering any solution within the ASP.NET stack (or "One ASP.NET" as I like to call it)...

...remember that it's things like IHttpHandler that sit at the bottom and serve one request (everything comes from IHttpHandler) while it's IHttpModule that's always watching and can see every request.

In other words, and HttpHandler sees the ExecuteRequestHandler event which is just one event in the pipeline, while HttpModules can see every event they subscribe to.

I hope this helps!

Sponsor: Thank you to my friends at Axosoft for sponsoring the Hanselman feed this week. Do check out their product! Imagine agile project management software that is brilliantly easy to use, blazingly fast, totally customizable, and just $7 per user. With OnTime Scrum, you won't have to imagine. Get started free.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

I'm realizing there's a number of subtle but important new things in the next version of VS that streamline some previously difficult tasks. For example, there's the .NET Framework, but .NET is also in Silverlight, the Windows Phone, the Xbox, etc.

If you create a regular Class Library it has a single Target Framework. However, if you are doing a multi-platform application and you want to maximize your code reuse, you can run into trouble as you may not have all libraries available on the smaller platforms.

These Portable Class Libraries (PCLs) will generate a managed assembly that can be referenced by Windows Phone 7, Silverlight, the Microsoft .NET Framework and Xbox 360 platforms. This really helps to maximize reuse of code and reduce the number of projects in multi-targeted application solutions.

If you create a new Portable Class Library, right click on it and hit Properties. You can target specific frameworks and the build system and Intellisense will adjust. Some libraries are on some device. For example, XML Serialization isn't on the Xbox 360, but WCF is on the Windows Phone.

Remember that Portable Class Libraries are constrained by design. You're targeting the lowest common denominator to maximize what you can use between projects. The MSDN article on Portable Class Libraries has a table that show what's available on each platform. You can do MVVM work across Windows, Metro style aopps, Silverlight and Windows Phone, for example.

Here's some good advice that David Kean sent me:

One thing [about] using portable [is that it] doesn’t mean you can’t use platform specific features, you just need to spend a little more time thinking about your dependencies. For example, instead of having a low level class that handles your persistence layer using the File APIs (which aren’t usable/available on Phone, Silverlight, etc), have it instead take work on an abstraction such as a stream, which these gets passed that from the platform specific project. Or have it call through an platform adapter (called out in my article), or inject the abstraction using your favorite IoC container (in my case Autofac, just published a portable version)

MSDN Help also shows what works with Portable Libraries as well so you're supported when looking at Help, Intellisense, and at Build time.

The BCL Blog mentioned that they are talking to the Mono guys about this as well. It'd be great to get Mono for Android and other frameworks as appropriate in here as well. I was excited to discover that this work was happening, even though it's been over a year in the making.

For folks like my friends at Rowi who have a great Windows Phone 7 application, or MetroTwit with a great WPF app, I wonder how Portable Class Libraries might change the architecture of their applications and enable cleaner builds and reuse scenarios they haven't thought of.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

Mom and Dad, it's a dangerous Internet. You like it and you use it but you don't understand it. I totally get that. I don't understand plumbing. I know that the sink drain goes into the bendy thing and then into the wall. After the pipe hits the wall, as far as I know, it's turtles all the way down. I assume the Internet feels about the same to you.

I don't want to condescend or imply that the web is a series of tubes. You're not interested in knowing all the details and I'm not a plumber, but there's a minimum amount of stuff you should know to be safe. You don't need to memorize this stuff, but it's nice to know generally where the pipes go and when to call a plumber. Or me.

Looking up web addresses

When you type in an address www.amazon.com in your browser, your computer queries the Internet's Yellow Pages and tries to find out exactly where amazon.com is. These yellow pages are called DNS (Domain Name Services). This is just like me taking your home address and getting a latitude and longitude location on a map, then going there.

Just like it's easier to remember an address like "6 Main Street" than some numbers like latitude and longitude. It's easier to remember "amazon.com" than it is to remember a number like 194.105.56.3. An address is a convenience.

However, do you trust the Yellow Pages? One day a book showed up on your doorstep, you reference it and it tells you where stuff is. What if an evil-doer dropped pretend Yellow Page books on everyone's doorstep and folks who wanted to go to the store were sent somewhere evil? Hopefully at some point you'd "feel wrong" about the directions you were given and you'd question yourself.

For the most part, you're usually OK, but if you ever type an address and go somewhere that feels wrong, ask someone. There are toolbars and weird little evil bits of software (called malware or adware or spyware) that can "hijack" your browser. They deliberately give your browser incorrect directions in order to get you to go to their site.

It'd be like calling the operator and asking for directions to the Safeway Market and having the operator give you directions straight to Thriftway. You didn't know you couldn't trust the operator!

See the picture below? It looks like a link to amazon.com and I'm about to click on it, but see the down at the bottom there's a little window that shows a different website. The blue link is under evil guy's control and can say anything, but the one at the bottom is a hint from your browser that something is fishy.

The browser you use might show this in a different way, but the idea is the same. If someone gives you a link that smells fishy, use your judgment. Develop a healthy - but not paralyzing - suspicion. Everyone in the world isn't out to get you, but pickpockets do exist.

Here's some hints on what to look for. Try to think about not as a scary computer thing but rather use the common sense you've developed in the real world. When you go to Macy's to shop, does it look and smell and feel like Macy's? How do you know it's not a fake Macy's façade that someone put up with cardboard?

Does the address match the logo?

Take a look at this screenshot. Is this a real Abercrombie & Fitch store? The logo says it is, but that address is kind of smelly, don't you think?

Lets say I start shopping at this fishy site anyway. When I start putting things into my shopping cart and giving a store money OR my personal information, a reputable site should change our conversation to a secure line.

Just like in spy movies we hear the lead say "Is this phone encrypted? Don't call me from an insecure line, do you want to get us all killed!?!" you want to think in the same terms.

A Private Conversation

Is your conversation with a website private? Here's the fake site on the left and the real one on the right. See how a little lock appeared? That means the conversation we're having with that site is private.

Now, please, read this part carefully, Mom and Dad. The lock says the conversation is private, but the lock doesn't say I should trust them. You can have a private conversation with a bad guy. There are bad sites with this little lock.

HTTPS (SSL) doesn't mean "I can trust this site," it means "this conversation is private." You still might be having a private conversation with Satan. - Scott Hanselman

Trust and Privacy are different things. "Do I trust this person" and "Is our conversation private?" are different questions. You want to answer yes to both questions before you give a company your credit card number.

I can click on the lock at the https://www.abercrombie.com website to see a bunch of techie stuff. That techie stuff is not as interesting as is the other locks and information. There's two green locks assuring me of the privacy of our interaction, but more importantly I can see I've never visited this site before.

But what if I know I have visited the site? What if I visit this site every day and now here it is saying I don't? This is a good time to look around and make sure I am where I think I am. Check the address again, just like you would in real life before you ring the doorbell.

Compare this to Amazon, a site I do visit all the time.

A Trusted Conversation

If you're going to do some online banking, you should expect to see that lock as soon as you get to the bank's site.

Large, reputable banks should use a special lock on their sites. See this https://www.bankofamerica.com site in three different browsers below? The address bar has turned green. This means that not only is our conversation private but that a company has checked to make sure it's really Bank of America. This means I can trust them AND our conversation is private. These are called "high assurance" or "extended validation" certificates if you want to tell your local credit union or community bank to get one.

Just like Scully and Mulder check other agent's IDs before talking to them, you should be checking the identification of websites you talk to.

If you (or Mom) had the Web of Trust installed, this is what you would have seen when visiting an evil site like this. I'm installing this free tool on Mom's machine today. It's a browser plugin that uses other people's experience to augment yours!

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

Say what you will about the past ridiculousness of .NET Framework versioning, since the confusion of .NET 3.5SP1 they've been trying to get it right. It's not the magic of Java Version 6 Update 31 (build 1.6.0_31-b05) but it's a start. O_o

Back in July of 2011 I wrote a post on Issues with .NET and Microsoft Product Versioning that got the attention of some folks. I was most concerned about some "platform updates" to .NET 4 and the way they were named. Meetings were had and those small updates now have simpler names versions like NET 4.0.1, etc.

I'm not going to tell you it's not confusing today. I do think that things are getting better and becoming less confusing. .NET 4.5 is a step in the right direction of transparency in versioning.

The .NET Framework can version in two ways. There are "side by side installs" and there are "in place upgrades." A major version means side-by-side and a minor version means in-place.

Side-by-side means that different versions of .NET can live together on the same machine.

In-place upgrade means that the CLR is the same but new libraries are added as well as bug fixes and performance improvements:

There's been some concern about how .NET 4.5 is an "in-place upgrade" of .NET 4. That means .NET 4.5 is still the v4CLR and adds new libraries as well as improvements to the core CLR itself.

Rick Strahl said on his blog:

Note that this in-place replacement is very different from the side by side installs of .NET 2.0 and 3.0/3.5 which all ran on the 2.0 version of the CLR. The two 3.x versions were basically library enhancements on top of the core .NET 2.0 runtime. Both versions ran under the .NET 2.0 runtime which wasn’t changed (other than for security patches and bug fixes) for the whole 3.x cycle. The 4.5 update instead completely replaces the .NET 4.0 runtime and leaves the actual version number set at v4.0.30319.

Rick has a great post with a lot of detail and information. However, respectfully, I don't think .NET 4.5 vs. .NET 4 is as different as Rick implies. In fact .NET 3 and .NET 3.5 both upgraded the system (and CLR) in place as well.

Perhaps if 3 and 3.5 were called .NET 2.5 and .NET 2.8 it would have made more sense. The community is always concerned about breaking changes, much like we are here with .NET 4 and .NET 4.5. Unfortunately reality and marketing names haven't always matched, but going forward I think we all agree that:

Major Version = New CLR

Minor Version = Bug fixes, new libraries

Revision = Bug fixes, no breaking changes, small improvements

.NET 4.5 is not a radically different side-by-side CLR. A new CLR would be a theoretical .NET 5 In my opinion.

Could something break with .NET 4.5? This is why it's in beta now, so now is the time to speak up. It's possible something could break but unlikely according the .NET Blog. Here are the known .NET 4.5 breaking changes - most are pretty obscure. The kinds of breaking changes I've seen myself in the wild have been primarily when folks are relying on reflection or internal data structures. These internals aren't public contracts so they may have changed. I realize that when a change breaks YOU it feels like a situation when "100% of applications will break....mine did!" situation. It sucks, but in fact there are minimal breaking changes in .NET 4.5.

Can I get .NET 2.0, 3.5, 4 and 4.5 apps all running together on my system? Yes.

Can I develop apps with different versions with Visual Studio 11 Beta? Sure, you can multi-target all these versions and even plugin more targeting packs. I'll do a blog post later this week on Portable Libraries, a new version in .NET 4.5 that makes creating libraries for any CLR (including Xbox, Phone, Mono and others).

Developing Safely for both .NET 4 and .NET 4.5

It's been implied on blogs that if you install .NET 4.5 on your machine that you can't safely develop for .NET 4. In Rick's post, he compares two DLLs on a .NET 4 machine and again after the .NET 4.5 in place upgrade. How can you target safely against .NET 4 if you've installed .NET 4.5? You don't have those .NET 4 DLLs anymore, right?

Actually you do. They are in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework.

Let's prove it on a machine with Visual Studio 11 Beta. I'll make a DLL and reference System.Web and make use of one of the added types in that assembly. Yes, it's a screenshot of code, but hang in there.

Now I'll change the properties of my project from .NET 4.5 to .NET 4. I won't change anything else. I'll build. Note that the type isn't there, I get a build error and I can't reference the namespace. You will know if you're using new .NET 4.5 functionality. The multi-targeting build system was designed for this and existed as far back as .NET 3.5. Those reference assemblies are there to catch this kind of thing.

So while .NET 4 and .NET 4.5 don't live side by side on your system at runtime, Visual Studio knows about all the different versions of .NET and the compiler will reference different versions when you build.

If you are making a client app, like WinForms, Console, WPF, etc, this is all automatic. Your app.config contains that fact that you need .NET 4.5 and you'll even get a prompt to install it.

So if I run my .NET 4.5 Console App on a .NET 4.0 machine now I get a nice dialog.

Looks like this technique doesn't work on ASP.NET (I would expect a Yellow Screen of Death)...I will talk to the team about that. I think this is a good thing and ASP.NET should respect it also.

UPDATE #2: The system will throw an error when an ASP.NET 4.5 application is deployed to an ASP.NET 4 system. The default templates on for ASP.NET 4.5 applications include the targetFramework attribute set to 4.5 like this:

This will throw a YSOD if you deploy a 4.5 to a 4 machine like this: "The 'targetFramework' attribute currently references a version that is later than the installed version of the .NET Framework."

UPDATE: If you really, really want to detect .NET 4.5 at runtime, don't check versions or build numbers. Check for the existence of the feature you want to use. For example, from this Stackoverflow question by Christian K, here's how to detect .NET 4.5 programmatically.

However, David from the CLR team (in the comments) says that this is not a good idea. He says to check if an important feature is there and use it. Don't cheat and infer .NET versions.

"The IsNet45OrHigher example is not what we'd recommend. By feature detection, we mean 'detecting the presence of a feature before you use that feature', <i>not</i> 'using the presence of a feature to determine what version of .NET you are runnning on."

Identifying the current operating system is usually not the best way to determine whether a particular operating system feature is present. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, test for the presence of the feature itself.

Sponsor: My sincere thanks to Axosoft for sponsoring this week's Hanselman.com feed! Imagine agile project management software that is brilliantly easy to use, blazingly fast, totally customizable, and just $7 per user. With OnTime Scrum, you won't have to imagine. Get started free.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.