January 2012 - Posts - Jon Galloway

January 2012 - Posts

ASUS Zenbook UX31 - First Look

I've been through several laptops over the years, three in the past two years. I had an old Dell beater as a fallback, but for a while my main laptop was a Dell Latitude XT2. The XT2 seemed promising - a small laptop with a touch screen - but poor drivers and slow performance made it barely usable. It was bad enough trying to do day to day work on it, but when I used it to give technical presentations it was flat out embarrassing. That's why, when I was up for a new work laptop, I jumped at the Lenovo W520. The W520 is an enormous brute of a machine in every sense - literally more powerful than most desktop machines, and not much smaller. That's fine, I thought - I'll happily trade convenience for a machine that actually works.

I tell you that history to explain why, when I was offered the opportunity to review an Intel Ultrabook, I was pretty skeptical. I reviewed some of the different options available and - while they looked good - I didn't expect a lot in the way of power, especially when I saw that the prices were pretty reasonable.

As I said, I was offered an Ultrabook in exchange for a review, so here's the disclaimer: I received an ASUS Zenbook 31 for free in the hope that I would mention it on my blog. Regardless, I only recommend things I personally endorse and would recommend. I'm disclosing this in accordance with the FTC's Guides Concerning the Use of Endorsements and Testimonials in Advertising. Just in case, I also cleared it with my employer's legal / corporate affairs team. I also made sure the agreement said that my review would be my honest opinion, and that's what this is. This is my opinion alone, and doesn't necessarily reflect the views of my employer.</disclaimer>

The offer was to review an Ultrabook from Intel's current lineup, so step one for me was to compare the options. There are a lot of good choices out there, and while I was interested in the Lenovo U300s (a pretty gorgeous machine) I kept coming back to the ASUS Zenbook. It stood out for a number of reasons, but one big one was the screen resolution. Just about every comparable laptop out there maxes out at a screen resolution of 1366x768 or 1440x900 (including the top MacBook Airs), the Zenbook UX31 goes all the way up to 1600x900. Based on recent history with trying to work and give technical presentations using small laptops, I wasn't interested in reviewing anything I couldn't do real work and consider presenting with. If you're looking for an ultrabook form factor laptop to do real work on (as opposed to web and media) I think those extra pixels are a big deal.

Unboxing

This laptop was very well packaged. It was obvious from the start that attention had been paid to quality and elegance, and I think it works. This felt like unpacking a quality consumer product, not your typical laptop box full of random papers and promotional CD-ROMS.

IMG_6172

After removing the small but solid Zenbook, I found a sturdy looking carrying case. As others have noted, a carrying case for this seemingly indestructible laptop seems like overkill, but it sure looks nice.

IMG_6173

After removing the Zenbook and the case (pictured later), you find a nice introductory card on top of a small box with other necessary but not beautiful stuff (owner's manual, warranty card, etc.). Again, opening this laptop feels like an experience.

IMG_6174

So at the risk of being incredibly nitpicky here, I found it odd that the Zenbook card was completely devoted to talking about features of the Zenbook, and none said anything like "You'll need to plug in your Zenbook before using it." Yes, I'm a computer guy who knows (expects) that laptop batteries won't stay charged during shipping and the dang thing needs to be plugged in when you open the package, but I'm thinking like a non-techy consumer who's buying a consumer electronic gizmo here. When I take the Zenbook out of the box and try to turn it on, nothing happens. The welcome card should cover that.

On to the actual laptop - the Zenbook!

IMG_6177

This is a good looking, solid machine. It's small but heavy. When I showed it to my 7yo daughter and asked what she thought it looked like, she said, "Expensive!" I agree, and while this doesn't come through in a blog post, the laptop itself feels very substantial. It's not heavy, but it feels hefty for its petite size.

The case is solidly constructed and looks nice.

IMG_6220

A Few (Minor) Complaints about the First Run Experience

For such a beautiful unboxing experience, I had (unrealistic?) expectations for the first run experience. Things went downhill a little bit when I turned the Zenbook on. The first prompt I got required me to accept an agreement to install the Bing Bar.

IMG_6183

What was especially frustrating with this prompt was that there was no choice - in order to start the machine up, I needed to agree to the Bing Bar license - the Next button is disabled until I do. That really broke the "fancy" feeling. Things continued in that direction after the installation completed, with a bunch of annoying dialogs:

Desktop -2

Look, I get that crapware manufacturers pay computer manufacturers money to bundle trial software, and that (kind of) benefits consumers by lowering prices. That's the real world. I think this could be done better, though. Either charge a bit more and ship a beautiful first run experience, or at least bundle all the lame crapware dialogs into one. The overlapping, uncoordinated dialogs feel cheap cheap cheap, which ruins an up-til-then beautiful experience. It's something I expect in a budget laptop, but not something as beautiful (and as beautifully packaged) as the Zenbook.

Curious, I took a quick look at the pre-installed goodies, and wasn't surprised to see quite a list:

2012-01-25 01h13_20

So, I could (and will) uninstall the junkware, but was a little disappointed to see it as a part of an otherwise beautiful setup install experience. I don't want to give the wrong impression here - these are minor annoyances, and don't really significantly detract from the actual use of this beautiful machine after the first few minutes. It's just that they've obviously invested a lot of effort in packaging, and it's a shame to see that emotional appeal damaged even in the slightest when I turn the machine on.

Fast

Regardless of any unwanted pre-installed goodies, this thing is snappy right out of the box. Without installing any updates or uninstalling anything, I got a 5.6 WEI.

2012-01-25 10h09_42

These are pretty fast scores. And, more important, so far this thing feels fast. I've been using it for a week and this thing just feels fast all the time.

Face Login

Okay, I'll talk more about this machine once I've used it for a few weeks, but I wanted to show off one cool feature - Face Login. The webcam locks in on you face and automatically logs you in, as shown below.

I've used a few webcam login systems, but none of them have worked near this well. The Face Login system really works - it's fast and it's fun.

Summary

So far I'm very impressed. While this post focuses on the first few hours with the laptop, the reality is that what's really important is all the hours that follow. I'll write I more detail once I've used this more, but this past week has shown me that this is an amazing laptop. If I was shopping for a new laptop today and my friend showed me this machine, I'd buy it... and I'm a hard sell.

Some more links for the Zenbook UX31:

Posted by Jon Galloway | with no comments
Filed under:

10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides

The ASP.NET configuration system is build around the idea of inheritance:

Each Web.config file applies configuration settings to the directory that it is in and to all of the child directories below it. Settings in child directories can optionally override or modify settings that are specified in parent directories. Configuration settings in a Web.config file can optionally be applied to individual files or subdirectories by specifying a path in a location element.

The root of the ASP.NET configuration hierarchy is the systemroot\Microsoft.NET\Framework\versionNumber\CONFIG\Web.config file, which includes settings that apply to all ASP.NET applications that run a specific version of the .NET Framework. Because each ASP.NET application inherits default configuration settings from the root Web.config file, you need to create Web.config files only for settings that override the default settings.

For a lot of sites, you don't really need to know about that - you can get by with one Web.config file for the site. But, knowing how the inheritance works - and how to control it - can really help out.

I've noticed that a lot of the questions I answer questions on forums, StackOverflow, and internal e-mail lists can be solved by better understanding how ASP.NET configuration inheritance and overrides work. And so, a bunch of tips about how ASP.NET configuration inheritance and overrides work! I'll start with some basics, but there are some towards the end I'll bet most ASP.NET developers don't know.

Tip 1: Using Web.config files in site subfolders

And ASP.NET website's Web.config is part of an inheritance chain. Your website's subfolders can have Web.config - an example is the Web.config file in an ASP.NET MVC application's View folder which does things like preventing directly viewing the View templates:

2012-01-12 23h57_09

This allows for setting general settings at the site level and overriding them when necessary. Any settings in the base Web.config that aren't overridden in the subfolder stay in effect, so the "child" Web.config can be pretty small. You can continue to nest them, so sub-sub-subfolders can get their own Web.config if needed. Some of the most common uses of subfolders are to restrict permission (e.g. requiring authentication or restricting access to resources), but you can also use them to do things like include default namespaces in Views, toggle handlers, etc.

Tip 2: Understand how your site Web.config inherits its settings

But there's an inheritance chain above the site, too. Here's a simplified version from the MSDN docs:

Configuration level

File name

File description

Server

Machine.config

The Machine.config file contains the ASP.NET schema for all of the Web applications on the server. This file is at the top of the configuration merge hierarchy.

IIS

ApplicationHost.config

ApplicationHost.config is the root file of the IIS 7.0 configuration system. It includes definitions of all sites, applications, virtual directories, and application pools, as well as global defaults for the Web server settings. It is in the following location:

%windir%\system32\inetsrv\config

Root Web

Web.config

The Web.config file for the server is stored in the same directory as the Machine.config file and contains default values for most of the system.web configuration sections. At run time, this file is merged second from the top in the configuration hierarchy.

Web site

Web.config

The Web.config file for a specific Web site contains settings that apply to the Web site and inherit downward through all of the ASP.NET applications and subdirectories of the site.

ASP.NET application root directory

Web.config

The Web.config file for a specific ASP.NET application is located in the root directory of the application and contains settings that apply to the Web application and inherit downward through all of the subdirectories in its branch.

ASP.NET application subdirectory

Web.config

The Web.config file for an application subdirectory contains settings that apply to this subdirectory and inherit downward through all of the subdirectories in its branch.

So your website's configuration's actually inherited a bunch of settings that were set at the server level. That's nice for a few reasons:

  1. It allows the ASP.NET / IIS teams to migrate settings that aren't commonly modified from the project template Web.config files to server defaults, keeping your Web.config files smaller and more readable. For example, ASP.NET 4 migrated a bunch of handler registrations to Machine.config, so the Empty ASP.NET Application Web.config is slimmed down to about 8 lines.
  2. You can override things at the server level as needed, and they'll take effect for all applications. For example, you can set <deployment retail="true"> on production servers to disable trace output and debug capabilities.
  3. You can find a lot of useful information in the Machine.config default settings since they're stored in plain text. For example, the ASP.NET Membership Provider has some defaults set for password requirements and the membership database, and you can look them up by looking in the appropriate .NET framework version's Machine.config. For a default installation of ASP.NET 4, that's found in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config with a quick search for <membership>.

Tip 3: Understand how your Web.config inherits IIS configuration settings

This overlaps a bit of Tip 2, but it bears repeating. Long-time ASP.NET developers (myself included) are prone to thinking of ASP.NET and IIS configuration separately, but that all changed with IIS 7. This is all pretty old news, as IIS 7 has been out for a while, but it hasn't been completely absorbed by ASP.NET developers.

CarlosAg summed this up well in a post from 2006(!) which explained The New Configuration System in IIS 7.  I'm not going to rehash his post here - go read it. Some important takeaways are that both the ApplicationHost.config and Machine.config feed into the configuration settings in your site's Web.config, as shown in Carlos' diagram:

In addition to the understanding how things work part of it, this is also good to know because - based on the info in Tip 2 - you can see what the base settings are, and how you can override them in your application's Web.config. This is why you can do pretty advanced things like configure rules on for the URL Rewrite Module in your application's web.config.

Of course, server administrators don't necessarily want to allow any application on the server to modify settings via Web.config, so there are configurable policies in the ApplicationHost.config which state whether individual applications can override settings. There's also an Administration.config file which controls things like Module registration.

There's one kind of new update to this list - using aspnet.config for Application Pool tuning. It's found in the same directory as Machine.config, and it's been around since .NET 2.0. However, as of ASP.NET 4 it's been expanded to handle things like concurrency and threading, as explained in Scott Forsyth's post, Setting an aspnet.config File per Application Pool. While not something most ASP.NET developers will need to use, it's good to know that you can control things like maxConcurrentRequestsPerCPU, maxConcurrentThreadsPerCPU and requestQueueLimit at the application pool level.

Tip 4: Location, location

While it's nice to be able to override settings in a subfolder using nested Web.config files, that can become hard to manage. In a large application, it can be difficult to manage settings because you can't see the effective permissions in one place. Another option is to use the <location> element to target settings to a specific location. For example, I previously showed how to use this to allow large file uploads to a specific directory in an ASP.NET application using the location element:

<location path="Upload">
    <system.web>

        <httpRuntime executionTimeout="110" 
                     maxRequestLength="20000" />
    </system.web>
</location>

Tip 5: Clearing parent settings when adding to a collection

Sometimes you want to remove all inherited settings and start fresh. A common place you'll see this is in handler, module, connection string and provider registration - places where configuration is used to populate a collection. Scott Guthrie blogged about an example in which just adding a new Membership Provider causes problems, because you end up with two providers - the default, and the one you just added. It's important to clear the collection before adding your new provider using the <clear/> element, like this:

<membership>
      <providers>
          <clear/>
          <add name="AspNetSqlMembershipProvider"
              type="System.Web.Security.SqlMembershipProvider, 
                    System.Web, Version=2.0.0.0, 
                    Culture=neutral, 
                    PublicKeyToken=b03f5f7f11d50a3a"
              connectionStringName="MyDatabase"
              enablePasswordRetrieval="false"
              (additional elements removed for brevity)
          />
      </providers>
</membership> 

As Scott explains, failure to <clear/> the collection first results in both providers attempting to handle membership, which probably isn't what you intended.

Tip 6: Locking settings with with allowOverride and inheritInChildApplications

You may need to prevent sub-applications from overriding or extending settings. You can do that with the allowOverride attribute, which does exactly what the name suggests - the same way a sealed class prevents changes via a derived class. The MSDN documentation summarizes this well:

You can lock configuration settings in ASP.NET configuration files (Web.config files) by adding an allowOverride attribute to a location element and setting the allowOverride attribute to false. Then within the location element, you can define the configuration section that you want to lock. ASP.NET will throw an exception if another configuration file attempts to override any configuration section that is defined within this locked location element.

Using a location element with an allowOverride=false attribute locks the entire configuration section. You can also lock individual configuration elements and attributes using lockItem, lockElements, lockAttributes, lockAllAttributesExcept, and lockAllElementsExcept.

That last part there - using attributes on sections - works because those lock attributes are among the general attributes inherited by section elements.

Tip 7: Disinheriting your child applications with inheritInChildApplications="false"

If you've got settings that should only apply to the parent application and shouldn't be inherited, you can use the inheritInChildApplications attribute on any section or location element. That makes the settings at the current level, but inheriting applications and subfolders don't have to bother with clearing and rebuilding configuration just to remove those settings.

This came up in a recent question on StackOverflow:  Unloading parts of a web.config file from a child application

Since Web.config is so heavily built on the concept of inheritance, it's not surprising that turning it off for a section can have some side effects. The aptly self-named "Run Things Proper Harry," a.k.a. rtpHarry, has written up two good posts covering usage and important things to be aware of.

Tip 8: Use configSource to separate configuration into separate files

While I've been discussing modification of Web.config settngs through inheritance, it only makes sense to mentions some useful ways to handle overriding Web.config settings.

Any Web.config section can be moved to a separate file by setting the configSource attribute to a file reference. I've mostly used this for handling connection strings, since it allows you a lot more flexibility over versioning and and deployment. Instead of having different Web.config files for each environment ("Oops! Just deployed the staging Web.config to production!!!"). It looks like this:

<configuration>
  <connectionStrings configSource="connectionStrings.config" />
  ...

Then your connectionStrings.config file only needs to change between environments, and can contain specific settings. It holds the contents of the element you're referring to, so it looks like this:

<connectionStrings>
  <add name="subtextData"
    connectionString="Server=.;Database=staging;Trusted_Connection=True;" />
</connectionStrings>

Another way I've seen this done is to have differently named connection strings config files for each environment (e.g. dev.config, staging.config, production.config). That allows you to check them all in to source control and not worry about getting files with the same name but different contents mixed up, but the tradeoff is that your Web.config in each environment needs to be updated to point to the right config source.

So, this is a handy trick, but isn't quite perfect. A better option is to use Web.config File Transformations.

Tip 9: Use Web.config Transforms to handle environmental differences

I don't hear as much about Web.config Transforms as I'd expect. Maybe they just work and everyone just quietly uses them and doesn't talk about it. But from the questions I see coming up over and over again, I'm not sure that's the case.

I love Web.config Transforms. At my first ASP.NET MVP summit, I was part of a feedback group discussing frustrations with deploying ASP.NET applications. Two themes that came up over and over were difficulties with packaging and managing configuration. That team later produced Web Deployment Packages (a nice format that packages files and settings for a site in a way that can be inspected and modified during installation) and Web.config Transforms.

All the new ASP.NET projects have Web.config transforms already set up - if you expand the Web.config node, you'll see that it's configured to create different settings for Debug and Release mode.

2012-01-17 14h51_29

It's really easy to use - your main Web.config has the base settings for your site, and whenever you build, the transforms for the appropriate build configuration (e.g. Debug or Release) are automatically applied. If you had a Test database that you wanted to use by default, but wanted your Release builds to run against the Production database, you could set it up so that your base Web.config connection string points to the Test Database connection string, like this:

<connectionStrings>
  <add name="ApplicationServices"
      connectionString="[TestDatabase]" />
</connectionStrings>

Then your Web.Release.config overwrites that to point at the Production database, like this:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="ApplicationServices" 
        connectionString="[ProductionDatabase]" 
        xdt:Transform="Replace" xdt:Locator="Match(name)"/>
  </connectionStrings>
</configuration>

The syntax is pretty straightforward, but you don't need to worry about that because the comments in the Web.Release.config file already show how to do that.

To be clear: unlike the other examples, this is something that happens at build time, not runtime.

I recently ran into an issue where I wanted to deploy something to AppHarbor and wanted to switch between a local SQL Compact database and the hosted database server, and Web.config Transforms worked just great there.

There's a lot more to talk about with Web.config Transforms that's beyond the scope here, such as:

  • You can create as many build configurations as you want, with different transforms for each configuration. This makes it simple to switch between different settings in your development environment - say, switching between several development databases or other application settings.
  • You can use the configuration transformation system with any XML file using the SlowCheetah Visual Studio extension. Scott Hanselman's written a post with more information on that here: SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file
  • Sayed (the Microsoft developer who's worked on both Web.config Transforms and the SlowCheetah extension) has also built a Package Once Publish Anywhere NuGet package which allows you to defer running the transforms until later, using a PowerShell command. That means you can build one Web Deployment Package with all the transforms included, and run them when you're going to deploy to a specific environment.

There's some good information on MSDN about Web.config Transforms:

Tip 10: Managing Application Restarts on Configuration Changes

There are a lot of moving parts in figuring out the configuration for a website, as illustrated above. For that reason, ASP.NET computes the effective settings for the site and caches them. It only recomputes them (and restarts the application) when a file in the sites configuration hierarchy is modified. You can control that on a section by section level using the restartOnExternalChanges property.

One place where configuration changes don't automatically get recomputed is for external config files set using configSource (as shown in Tip 8). You can control that by setting restartOExternalChanges="true" for that section. There's an example on MSDN that shows this in more detail by creating an external configuration file which is loaded via the configuration API (not referenced via configSource), then toggling the restartOnExternalChanges property and showing the differences in operation.

Summary

The ASP.NET Configuration system does quite a bit - I didn't even mention big topics like using the API for reading and writing values to both local and external config files or creating custom configuration sections. This post focuses on one aspect: getting things done by understanding and leveraging inheritance and overrides. Hopefully this gives you both some new tools for effectively handling configuration and some background that helps in troubleshooting when configuration is working as you'd like.

Are there any essential tips that I missed?

Posted by Jon Galloway | 57 comment(s)
Filed under:

Excerpt Old Posts - A WordPress Plugin to get around the Feedburner 512K Limit

Summary

If you've got a WordPress blog and use Feedburner, you may notice that the posts stop updating. It's often due to a limitation on Feedburner that stops updating if your feed exceeds 512K. I wrote a simple plugin called Excerpt Old Posts that fixes that problem by showing Full Text for recent posts and Summary for older posts.

Background

I run a podcast website (Herding Code podcast) on WordPress. The feed's probably the most important part of that site, since it's how people subscribe, feeds into iTunes and other podcast directories, etc. We put some work into the show notes, so I definitely want full text for each post in the feed. For users who just find the podcast, I want them to be able to find all our episodes in iTunes or other feed sources. I want a full feed - all text for all the posts.

We use Feedburner for some advanced feed management features, especially

  • Podcast support (it handles all the funky iTunes tags)
  • Tracking and analytics
  • Ability to change hosting without breaking the feed
  • Probably some other stuff I'm forgetting about - I've been using Feedburner for a long time

The Feedburner 512K feed limit

Unfortunately, Feedburner's got a limit of 512K per feed. If you exceed that limit, the feed just stops updating. I've run into this several times - I'd post a new show, and it wouldn't show up in Feedburner. I'd go through the standard Feedburner troubleshooting steps:

  • Manually ping Feedburner to make sure it knew there was something new
  • Check the Feedburner Troubleshootize page, which would lie to me tell me my feed was "quite healthy."
  • Eventually I'd give up and just Resync the feed (the so-called nuclear option)

Finally, when I'd attempt to Resync, Feedburner would tell me what was wrong - the feed was too big: "Feed Error: Your Feed Filesize is Larger than 512K"

There are two problems here:

No compliants on the first problem, Feedburner probably needs to set some limits on feed size or they'd grow like crazy. The big problem is that there's no notification, even in the admin interface, until you try to resync the feed.

My first (lame) solution: Compromise on quantity or quality

If you search around, you'll see that's the common suggestion - go in to to the Reading settings and either change the feed to show a summary for each post, or limit the number of items in the feed.

That solves the problem, but it doesn't make me - or our listeners - happy. As I explained above, everyone wants the Full Text for new content, and new subscribers want to see all shows listed when they subscribe.

What I really want is a feed that has Full Text for most of our newest posts and Summary for our old posts. That lead me to a slightly better solution.

My second (slightly less lame) solution: Hack around in feeds-rss2.php

After a while, decided to dig around and find out where the feed was actually written out. I found that my RSS feed was being written out in feeds-rss2.php, and wrote some ugly but workable code that runs a simple counter and switches from full posts to summaries after the counter hits a threshold. If you need that modified feeds-rss2.php for some reason, it's here. I hope you don't use it, though, because there's a problem: the next time I updated to the newest version of WordPress, my feed broke again.

My third (best) solution: Wrap this logic up in a plugin

Of course, the problem with tweaking internal code is that it gets overwritten when you update. The right way to extend WordPress is to create a plugin. That way your changes are all wrapped up nicely in a way that survives updates. And, also nice, the changes are easy to share with others.

This was my first WordPress plugin, and I'll save that process for another post. The important thing is that the plugin's got the Works On My Machine certification and is up in the WordPress Plugins Directory, titled Excerpt Old Posts. Yes, that's a kind of boring name.

It's pretty easy to use:

Add the Plugin in the WordPress Plugin settings:

In your admin settings, Go to Plugins / Add New. Click on Search and type in "Excerpt Old Posts"

Install the plugin and activate it.

Actually, that's really all you have to do if you want the default number of full posts (50) in your feed. You can check your feed if you'd like - you should now see that the 50 most recent items are showing Full Text, and the older ones are just showing the short Summary.

Changing the number of full posts shown in your feed

There's just one new setting available - the number of Full Text posts you'd like in your feed. Rather than adding a new settings page, I extended the Reading page. It seemed simpler to me - if I end up adding more settings I'll set up a new settings page for the plugin. You can see the new setting below:

WordPress - Excerpt Old Posts

That's it, hope you like it. If you have problems, I'd recommend using the dedicated forum for this plugin rather than the comments on this post, as you're more likely to get a timely response.

Posted by Jon Galloway | 1 comment(s)
Filed under: ,
More Posts