Scott Hanselman

How to write or burn a CD (CD-R) that includes CD-Text with ImgBurn

July 27, 2011 Comment on this post [14] Posted in Tools
Sponsored By

CD with CD-Text in my carOne of the greatest, coolest, but sadly least known and least often used tech things about CDs is "CD-Text." What is it? From Wikipedia:

CD-Text is an extension of the Red Book Compact Disc specifications standard for audio CDs. It allows for storage of additional information (e.g. album name, song name, and artist) on a standards-compliant audio CD.

Phrased differently, you'll be able to see the track details on your car CD player! This has been out for 14 years and I can count on one hand the number of times I've actually SEEN a CD in my car have text associated with it.

This evening I was putting together a Mix CD for my brother-in-law's upcoming wedding. I put together a lovely compilation from a list of songs they gave me, and even managed to fit in 79 minutes and 48 seconds. This is extra awesome because a CD holds 80 minutes. I bought the MP3s legally, and then burned them. When I went into the car to test the CD, I saw only DISC ---, TRACK ---, ARTIST ---.

I said to my self, "Self, this is weak sauce." I put all this work into the CD but I get hyphens instead of love? So I started doing some research and trying different tools.

I found ImgBurn (download link) to be the burner that gave me the most control while still maintaining an easy interface.

Start up ImgBurn, and from the Tools Menu select, "Create CUE File." What's a CUE file? It's a track that specifies exactly how to lay out the tracks on a CD before you burn them. The CUE includes not only the MP3s you want to burn, but also the gaps between songs, song length, the song text, etc.

You can make them in Notepad if you are really showoff Linux User who just has to do everything in Vim someone who likes to do things manually. Here's an example snippet of my CUE file, just so you know what one looks like.

TITLE "Vusi and Philile's Wedding CD"
PERFORMER "Various Arists"
FILE "Brenda Fassie - Wedding Day.mp3" MP3
REM FILE-DECODED-SIZE 04:04:33
TRACK 01 AUDIO
TITLE "Wedding Day"
PERFORMER "Brenda Fassie"
INDEX 01 00:00:00
FILE "04 Giving Myself.mp3" MP3
REM FILE-DECODED-SIZE 04:14:56
TRACK 02 AUDIO
TITLE "Giving Myself"
PERFORMER "Jennifer Hudson"
INDEX 01 00:00:00
....etc.... But insi

ImgBurn has a nice CUE File Creator/Editor. Tip: Be sure to set the "Default CD-Text" for the disc and the track to pull from the MP3s ID3 Tags. This is just the default. You can change this for each song later. Click each song and, if need be, change the CD-TEXT to Custom and put in whatever you like. Perhaps rather than song titles, put in messages to your sweetie?

Create CUE File for CD-Text in ImgBurn

When you click OK, you can save your .cue file for later use. Later, in Write Mode in ImgBurn, click the Folder button up there by "Source" and select your .cue file. All your MP3s will automatically be loaded up and queued for write.

ImgBurn Main Screen with my CUE file ready to burn 

Now, when I burn my CD, I see this on my car's dashboard, which gives me GREAT satisfaction, as it should you, Dear Reader.

 CD with CD-Text in my car

Doesn't this just make you want to burn some CDs with CD-Text and go see where they work? It did me. Enjoy.

NOTE: iTunes includes some CD-Text support, but it doesn't always work. Apparently there are two ways to burn CD-Text and iTunes doesn't seem to do the more compatible one. I like a little more control and that's why I prefer ImgBurn.

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.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Updated for 2011 - McDonald's WiFi Guide with updates for Mac OS X Lion and Windows 7

July 26, 2011 Comment on this post [41] Posted in Musings
Sponsored By

There was a picture going around on Twitter today of the McDonald's FREE WiFi Connection instructions, looks like they are from Australia, copyright 2008.

354952917

Of course, this isn't the latest and greatest guide to connect to WiFi at McDonald's, so I've included an updated guide here for your reference.

Updated McDonald's WiFi Instructions

The high quality PDF is available as well for printing or distributing at McDonald's. But who would do such a thing

Enjoy. ;)

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.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

A Social Media Brand Primer: Managing your (personal) brand with Twitter, Facebook, LinkedIn, YouTube, etc.

July 25, 2011 Comment on this post [1] Posted in Blogging
Sponsored By

IMG_1339 I was speaking with a friend recently who manages social media for a large company you've heard of who is really just making a hard push into online social media. I put together a list of questions, opinions and thoughts on the subject of managing one's personal brand with Social Media.

While I consider myself primarily to be a teacher, writer and speaker, I realize that I've used Social Media to amplify my words. First, intuitively, and in recent years, recently with some direction and planning. I don't personally apply these analytics to myself as I'm just a "personal brand," but I would recommend that legitimately famous people and companies be more measured. Here's some of the things one needs to think about when deciding to go online in full force. I've spoken on these topics at a number of large blogging conferences (as a side gig) and I'm always interested in discussing the possibility of speaking at your event.

Your thoughts, suggestions, areas I've missed and corrections are always appreciated, Dear Reader.

  • What does success look like? Don't just pull numbers out of thin air. Compare the stats of existing sites and decide what reasonable metrics are for your pages/projects/campaigns. Too often folks come up with large sounding numbers like "2000 likes on FB," then get 3000 and call the campaign a radical success. How much did it cost to hit those 3000 people? 30k? If so, why didn't you send them all $10 and ask them to Like you? Always figure out what your $ dollars per action come down to and determine what is a reasonable value for you.
  • Who are you IRL (In Real Life) and who are you online? How are these people/brands different? If your brand is not hip offline, how can you change that perception online? If you decide to be something online you (or your brand) is not, can you sustain it? Will your online brand change offline perceptions?
  • What is authenticity to your audience? The word "authentic" is overused, but there's still value in discussion of it. It's different from each audience! What does 'keeping it real' mean to programmer blogs? Hair blogs? Political blogs? If your audience smells chicanery on your part, they will destroy you (i.e. When keeping it real goes wrong).
  • How does your X audience differ from your Y audience? Do your FB people like coupons? Perhaps your Twitter people like exclusives? Maybe your Google+ folks like pictures. Don't just throw something out there and hope it works. Write down (that means track) what you're doing on each network with each idea, and track the results. Audience * Campaign * Social Network = Lots of combinatorics. Figure out your formula, then stick with it. Going with your gut (or your social media expert's gut) is just sloppy.
  • Is a Social Media expert a real thing? Or are they just people who speak more declaratively (or louder) than others? Can a 22 year old be a Social Media Expert? Can a 50 year old? Turns out that Social Media, no matter how you spin it, is still spin. When it comes to brands and brand managements it's a combination of classic PR and marketing, along with some new tools. Have the rules changed? Human behavior governs the system, the tools only magnify and accelerator the results. Is your social media expert telling you how the tools work and showing your what buttons to click, or are they talking about the larger picture? How do these tools make your brand or campaign operate at internet speed, governed by human behavior (as we understand it?)
  • How can Internet Speed work for and against, you? It's all then magnified by the speed of the internet. Results come faster, both good and bad. When you do something wrong, the Greater Internet Dickwad Theory will come into play and the trolls will descend upon you. Know that they are there and be ready to defend against them with truth and candor and, if necessary, capitulation and deference. Snowballs roll downhill fast on the internet. Don't get behind it. 
  • Is your brand defined? Do you have an established identity before social media? Often brands in trouble or brands just getting starting out tried to solve two problems at once. One, what's our social media plan? And two, who are we? You have to crawl before you run, and you ought to know what you stand for before you tweet. Takeyah Young talks about "standing in your values." Decide what you are, what you value and what you have to say. Social Media won't let you figure that out, it will only magnify it. Know who you are before you jump in.
  • Don't give Bile a Permalink. When you put something on the Internet, it's there forever, even if you delete it. Someone downloaded it, screenshotted it, Google cached it, someone took a picture of the screen. Regardless, it's there. If you are a d*ck online, then you've give that meanness a permanent link. A "permalink." Not only were you mean, but you've given your audience a way not only to link to it, but also to amplify and spread it.
    • Remember what happened to Kenneth Cole (the American Shoe Designer) on Twitter? I propose kindness, thoughtfulness, deference and appreciation for your audience, regardless of if you are a person online or if you are a person behind or speaking for a brand. While the rest of the Internet is mean (especially YouTube commenters!) I propose we double-down with kindness.
  • Be consistent in your voice - Your brand (or yourself) should feel similar in tone everywhere. If you're a sweetheart on your blog and a complainer on Twitter you are putting out an inconsistent face, especially for your audience that might follow you in both places. This gets back to defining what you want to express, and who you want to be (hopefully this is close to who you actually are!) online.
  • Know why you are 'followed" and be OK with it -  If your goal is to express yourself, then express yourself and be done with it. However, if your goal is to amplify some message, be aware of why your followers follow you in the first place. Are you a font of information? Is that how they found you and do they expect more? Are you a bringer of coupons or useful links? Perhaps, as mentioned before, different social networks have different expectations. Remember, only put more work into things you want more of. If you want more of the same kind of follower, keep giving them what they expect.
  • Separate the Personal and Professional. Or don't, but Decide. Where does your professional brand stop and your personal one start? Do you give our your phone number to the world like Scoble? Or do you blog and tweet under a pseudonym? Are you an open book or a mystery? Be conscious about the decisions you make and be aware of their pros and cons. If you blog under a nom de plume, is it at least unique (i.e. does it have Google Juice?) and findable? Do you want it to be? If you are blogging or using Social Media to beef up your resume, how do they relate to each other?
  • Know your Tools - While I've said that there shouldn't be an overemphasis on the tools, not knowing how The System works can almost be as damaging to your brand as being a jerk. It looks unprofessional. 
    • Recently I came upon a Facebook Profile for a reasonably famous company. They had reached the limit of 5000 friends and their page was turned into a giant billboard that said "we've reached the limit, please go to Profile #2, called Giant Company #2." You can imagine what I found on Profile #2. Yes, a link to Profile #3. This company (or its genius social media consultant) didn't know the difference between Facebook Pages and Profiles, nor had they found the Facebook Page Migration Tool. I wanted to "Like" this company, but when arriving to their site, I instead received a Task. I didn't come here for a new "To-do," I came here to connect with you! Make it easy, or you won't make it at all. 
    • I interacted with a famous actress on Twitter recently who would only reply with direct messages. That means, I would @reply to her and she would "DM" me back. I asked her why and she said, "I don't like to litter my page with replies." While it's nice that she has an opinion, this actually made her page look like a purely one-way conversation. Not only that, but our conversation was stilted at best as I moved between replies and direct messages. Bless her for trying, but she wasn't using the tools effectively.

Hope this helps!

Related Links and Resources

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.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

CoffeeScript, Sass and LESS support for Visual Studio and ASP.NET with the Mindscape Web Workbench

July 23, 2011 Comment on this post [30] Posted in ASP.NET | ASP.NET MVC | Open Source | Tools
Sponsored By

imageThere's some really impressive stuff happening in the .NET Community lately. Folks are reaching outside their standard built-in tools and pulling inspiration from everywhere. It's been said that (some) Microsoft developers don't like to use tools or technologies that aren't built in to Visual Studio. However, myself and others have been pushing the concept of LEGO blocks snapping together. Rather than thinking of Visual Studio as a giant single block, consider it as a small block amongst many others. Feel empowered to choose the technologies that work for you and discarding the ones that don't. I talked about this LEGO analogy in my DevDays keynote in The Netherlands earlier in the year.

Snap in tools like the HTML5 Web Standards Update for Visual Studio, loggers/profilers/debuggers like Glimpse, MiniProfiler and ELMAH, Package Managers like NuGet and OpenWrap,  all work together to make your development experience more enjoyable (and some new Visual Studio Styles/Themes and a little fresh wallpaper never hurt either! You can even make VS2010 look like 2008 if it make you happy).

One of the most impressive (free!) tools I've seen lately is the Mindscape Web Workbench. It is a 100% free plugin for Visual Studio 2010 to provide CoffeeScript, Sass and Less editing.

What? CoffeeScript? Sass? Less? What are these silly names and why should I care? Well, remember when I blogged about "fanciful names?" These are some names you'll want to know about. Here's a little about each and how Mindscape makes them fun for Visual Studio Developers.

CoffeeScript

"CoffeeScript is a little language that compiles into JavaScript." I've blogged a few times lately about how JavaScript is becoming not just THE ubiquitous language on the web, but also a valid target for high level languages to compile to. Script# compiles C# to JavaScript, GWT compiles to JavaScript, ClojureScript compiles to JavaScript, etc. However, each of these languages has semantics that require some significant mapping to JavaScript. They aren't JavaScript and don't know about it.

Here's the difference with CoffeeScript. "The golden rule of CoffeeScript is: "It's just JavaScript". The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime."

CoffeeScript "uplevels" JavaScript to make it more expressive and more idiomatic. You know when you're explaining something and you can't think of a word? Or perhaps you don't know the right word? CoffeeScript adds those new words to JavaScript and you find yourself going, YES! That's what I meant to say!

For example, from their website, here's some CoffeeScript:

# Assignment:
number = 42
opposite = true

# Conditions:
number = -42 if opposite

And here's what it "compiles" into:

number = 42;
opposite = true;
if (opposite) {
number = -42;
}

So what, you say. How about:

# Existence:
alert "I knew it!" if elvis?

Turning into...

if (typeof elvis !== "undefined" && elvis !== null) {
     alert("I knew it!");
}

Now we're talking. See how one is more expressive (and more enjoyable) then the other? This has a multiplying effect and makes your CoffeeScript code more expressive and your resulting JavaScript more robust.

list = [1, 2, 3, 4, 5]

square = (x) -> x * x

math =
root: Math.sqrt
square: square
cube: (x) -> x * square x

cubes = (math.cube num for num in list)

becomes

list = [1, 2, 3, 4, 5];
square = function(x) {
return x * x;
};
math = {
root: Math.sqrt,
square: square,
cube: function(x) {
return x * square(x);
}
};
cubes = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = list.length; _i < _len; _i++) {
num = list[_i];
_results.push(math.cube(num));
}
return _results;
})();


Remember how jQuery made you feel empowered? Released from tedious DOM code? Well, CoffeeScript does that for tedious JavaScript code.

Here's what it looks like in Visual Studio. Oh, yes.

CoffeeScript in Visual Studio

All this is enabled by the Free Web Workbench.

Sass

CSS is great and we all have a love hate relationship with it. When it works, it's great. Demos are nice, but the reality of CSS (much like that of JavaScript) is that it never quite reads like the fine poetry you were hoping for.

Two syntaxes are trying to improve on CSS in the same way that CoffeeScript improves on JavaScript. Remember that the reality is we can't change CSS and JavaScript, but we can change the Domain Specific Language that we write them in. You can't change Aseembler, but you can use C. Then layer in #defines, or perhaps just use C++...you get the idea. Up level your abstractions and favor the more expressive language.

Sass could mean Super Awesome Style Sheets. It's a meta-language on top of CSS. A better, redesigned CSS that is still a super set of CSS itself. CSS, cascading though it is, is still very flat.

If you write this SASS, it makes sense, doesn't it? It's intuitive and you might even think it's CSS as it is.

.fakeshadow {
border: {
style: solid;
left: {
width: 4px;
color: #888;
}
right: {
width: 2px;
color: #ccc;
}
}
}

Here's the resulting CSS:

.fakeshadow {
border-style: solid;
border-left-width: 4px;
border-left-color: #888;
border-right-width: 2px;
border-right-color: #ccc; }

This clean nesting works with #IDs of course as well such that this Sass:

#navbar {
width: 80%;
height: 23px;

ul { list-style-type: none; }
li {
float: left;
a { font-weight: bold; }
}
}

expands to this valid CSS:

#navbar {
width: 80%;
height: 23px;
}
#navbar ul {
list-style-type: none;
}
#navbar li {
float: left;
}
#navbar li a {
font-weight: bold;
}

Which would you rather write? I'm sold.

Sass uses an indentation syntax primarily but you can use brackets rather than indentations and semicolons rather than new lines. It's up to you. I like mine to look like nested CSS.

Your Sass files are converted into CSS as you click save in Visual Studio. It's a wonderfully clean integration.

Sass is sassy CSS

Sass is attractive because you really don't need to learn another syntax. You just use scoping and indenting rules you already know and you get cleaner CSS.

But, there's another alternative...

Less

Less extends CSS and adds more dynamic behaviors, variables, functions and more. Because it's more complex and a more dynamic translation, LESS actually runs on the client side and is supported by a client side JavaScript file called http://lesscss.googlecode.com/files/less-1.1.3.min.js.

Because of this, the Web Workbench doesn't do the same automatic developer-time conversion of LESS files. For me, this makes LESS (ahem) less attractive.

That said, you still these features from the Web Workbench, which is nothing to sneeze at.

  • Syntax highlighting
  • Intellisense
  • Warnings of syntax errors
  • Warnings of unknown variables and mixins
  • Go to variable or mixin definition

Here's an example LESS file...

@the-border: 1px;
@base-color: #111;
@red: #842210;

#header {
color: @base-color * 3;
border-left: @the-border;
border-right: @the-border * 2;
}
#footer {
color: @base-color + #003300;
border-color: desaturate(@red, 10%);
}

This is then compiled and results this CSS. Note what happened with functions, statements and variables:

#header {
color: #333;
border-left: 1px;
border-right: 2px;
}
#footer {
color: #114411;
border-color: #7d2717;
}

Interesting stuff.  I think it's important not only that you, Dear Reader, give this stuff a good hard look, but that you continue to look for ways that the open source community, both .NET and otherwise, are innovating. You maybe able to integrate these tools easily into your existing projects and not only have more fun but be more productive.

Thanks so much to the folks at Mindscape for releasing this free and elegant tool!

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.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

NuGet Package of the Week #9 - ASP.NET MiniProfiler from StackExchange rocks your world

July 22, 2011 Comment on this post [40] Posted in ASP.NET | ASP.NET Ajax | ASP.NET MVC | NuGet | NuGetPOW | Open Source
Sponsored By

Glimpse, MiniProfiler and ELMAH equals Love and Kittens (VENN DIAGRAM)I LOVE great debugging tools. Anything that makes it easier for me to make a site correct and fast is glorious. I've talked about Glimpse, an excellent firebug-like debugger for ASP.NET MVC, and I've talked about ELMAH, and amazing logger and error handler. Now the triad is complete with MiniProfiler, my Package of the Week #9.

Yes, #9. I'm counting "System.Web.Providers" as #8, so phooey. ;)

Hey, have you implemented the NuGet Action Plan? Get on it, it'll take only 5 minutes: NuGet Action Plan - Upgrade to 1.4, Setup Automatic Updates, Get NuGet Package Explorer. NuGet 1.4 is out, so make sure you're set to automatically update!

The Backstory: I was thinking since the NuGet .NET package management site is starting to fill up that I should start looking for gems (no pun intended) in there. You know, really useful stuff that folks might otherwise not find. I'll look for mostly open source projects, ones I think are really useful. I'll look at how they built their NuGet packages, if there's anything interesting about the way the designed the out of the box experience (and anything they could do to make it better) as well as what the package itself does.

This week's Package of the Week is "MiniProfiler" from StackExchange.

MiniProfiler for ASP.NET

Each are small bad-ass LEGO pieces that make debugging, logging and profiling your ASP.NET application that much more awesome.

So what's it do? It's a Production Profiler for ASP.NET. Here's what Sam Saffron says about this great piece of software Jarrod Dixon, Marc Gravell and he worked on...and hold on to your hats.

Our open-source profiler is perhaps the best and most comprehensive production web page profiler out there for any web platform.

Whoa. Bold stuff. Is it that awesome? Um, ya. It works in ASP.NET, MVC, Web Forms, and Web Pages.

The powerful stuff here is that this isn't a profiler like you're used to. Most profilers are heavy, they plug into the runtime (the CLR, perhaps) and you'd avoid messing with them at production time. Sometimes people will do "poor man's profiling" with high performance timers and log files, but there's always a concern that it'll mess up production. Plus, digging around in logs and stuff sucks.

MiniProfiler will profile not only what's happening on the page and how it renders, but also separate statements whose scope you can control with using() statements, but also database access. Each one is more amazing.

First, from an ASP.NET application, install the MiniProfiler package via NuGet. Decide when you will profile. You can't profile everything, so do you want to profile local requests, just requests from administrators, or from certain IPs? Start it up in your Global.asax:

protected void Application_BeginRequest()
{
if (Request.IsLocal) { MiniProfiler.Start(); } //or any number of other checks, up to you
}

protected void Application_EndRequest()
{
MiniProfiler.Stop(); //stop as early as you can, even earlier with MvcMiniProfiler.MiniProfiler.Stop(discardResults: true);
}

Add a call to render the MiniProfiler's Includes in a page, usually the main layout after wherever jQuery is added:

<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
@MvcMiniProfiler.MiniProfiler.RenderIncludes()
</head>

The, if you like, put some using statements around some things you want to profile:

public class HomeController : Controller
{
public ActionResult Index()
{
var profiler = MiniProfiler.Current; // it's ok if this is null

using (profiler.Step("Set page title"))
{
ViewBag.Title = "Home Page";
}

using (profiler.Step("Doing complex stuff"))
{
using (profiler.Step("Step A"))
{ // something more interesting here
Thread.Sleep(100);
}
using (profiler.Step("Step B"))
{ // and here
Thread.Sleep(250);
}
}

using (profiler.Step("Set message"))
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
}

return View();
}
}

Now, run the application and click on the chiclet in the corner. Open your mouth and sit there, staring at your screen with your mouth agape.

Mini Profiler rocks your world with stats right in your page

That's hot. Notice how the nested using statements are nested with their timings aggregated in the popup.

If you want to measure database access (where the MiniProfiler really shines) you can use their ProfiledDbConnection, or you can hook it into Entity Framework Code First with the ProfiledDbProfiler.

If you manage connections yourself or you do your own database access, you can get Profiled connections manually:

public static MyModel Get()
{
var conn = ProfiledDbConnection.Get(GetConnection());
return ObjectContextUtils.CreateObjectContext<MyModel>(conn);
}

Or, if you are using things like Entity Framework Code First, just add their DbProvider to the web.config:

<system.data>
<DbProviderFactories>
<remove invariant="MvcMiniProfiler.Data.ProfiledDbProvider" />
<add name="MvcMiniProfiler.Data.ProfiledDbProvider" invariant="MvcMiniProfiler.Data.ProfiledDbProvider"
description="MvcMiniProfiler.Data.ProfiledDbProvider"
type="MvcMiniProfiler.Data.ProfiledDbProviderFactory, MvcMiniProfiler, Version=1.6.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3" />
</DbProviderFactories>
</system.data>

Then tell EF Code First about the connection factory that's appropriate for your database.

I've spent the last few evenings on Skype with Sam trying to get the EF Code First support to work as cleanly as possible. You can see the checkins over the last few days as we bounced back and forth. Thanks for putting up with me, Sam!

Here's how to wrap SQL Server Compact Edition in your Application_Start:

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

//This line makes SQL Formatting smarter so you can copy/paste
// from the profiler directly into Query Analyzer
MiniProfiler.Settings.SqlFormatter = new SqlServerFormatter();

var factory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
var profiled = new MvcMiniProfiler.Data.ProfiledDbConnectionFactory(factory);
Database.DefaultConnectionFactory = profiled;
}

Or I could have used SQLServer proper:

var factory = new SqlConnectionFactory("Data Source=.;Initial Catalog=tempdb;Integrated Security=True");

See here where I get a list of People from a database:

 (45)

See where it says "1 sql"? If I click on that, I see what happened, exactly and how long it took.

SQL Profiler

It's even cooler with more complex queries in that it can detect N+1 issues as well as duplicate queries. Here we're hitting the database 20 times with the same query!

 (46)

Here's a slightly more interesting example that mixes many database accesses on one page.

Detecting Duplicates

Notice that there's THREE chiclets in the upper corner there. The profiler will capture GET, POSTs, and can watch AJAX calls! Here's a simple POST, then REDIRECT/GET (the PRG pattern) example as I've just created a new Person:

Creating a person and profiling them

Notice that the POST is 141ms and then the GET is 24.9. I can click in deeper on each access, see smaller, trivial timings and children on large pages.

I think that this amazing little profiler has become, almost overnight, absolutely essential to ASP.NET MVC.

I've never seen anything like it on another platform, and once you've used it you'll have trouble NOT using it! It provides such clean, clear insight into what is going on your site, even just out of the box. When you go an manually add in more detailed Steps() you'll be amazed at how much it can tell you about your side. MiniProfiler works with WebForms as well, because it's all about ASP.NET! There are so many issues that pop up in production that can only be found with a profiler like this.

Be sure to check out the MiniProfiler site for all the detail and to download samples with even more detail. There's lots of great features and settings to change as seen in just their sample Global.asax.cs.

Stop what you're right doing now, and go instrument your site with MiniProfiler! Then go thank Jarrod Dixon, Marc Gravell and Sam Saffron and the folks at StackExchange for their work.

UPDATE - July 24th

Some folks don't like the term "profiler" to label what the MiniProfiler does. Others don't like the sprinkling of using() statements and consider them useless, perhaps like comments. I personally disagree, but that said, Sam has created a new blog post that shows how to automatically instrument your Controller Actions and View Engines. I'll work with him to make a smarter NuGet package so this is all done automatically, or easily optionally.

This is done for Controllers with the magic of the MVC3 Global Action Filter:

class ProfilingActionFilter : ActionFilterAttribute
{
IDisposable prof;

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var mp = MiniProfiler.Current;
if (mp != null)
{
prof = MiniProfiler.Current.Step("Controller: " + filterContext.Controller.ToString() + "." + filterContext.ActionDescriptor.ActionName);
}
base.OnActionExecuting(filterContext);
}

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
if (prof != null)
{
prof.Dispose();
}
}
}

And for ViewEngines with a simple wrapped ViewEngine. Both of these are not invasive to your code and can be added to your Global.asax.

public class ProfilingViewEngine : IViewEngine
{
class WrappedView : IView
{
IView wrapped;
string name;
bool isPartial;

public WrappedView(IView wrapped, string name, bool isPartial)
{
this.wrapped = wrapped;
this.name = name;
this.isPartial = isPartial;
}

public void Render(ViewContext viewContext, System.IO.TextWriter writer)
{
using (MiniProfiler.Current.Step("Render " + (isPartial?"parital":"") + ": " + name))
{
wrapped.Render(viewContext, writer);
}
}
}

IViewEngine wrapped;

public ProfilingViewEngine(IViewEngine wrapped)
{
this.wrapped = wrapped;
}

public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
var found = wrapped.FindPartialView(controllerContext, partialViewName, useCache);
if (found != null && found.View != null)
{
found = new ViewEngineResult(new WrappedView(found.View, partialViewName, isPartial: true), this);
}
return found;
}

public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
var found = wrapped.FindView(controllerContext, viewName, masterName, useCache);
if (found != null && found.View != null)
{
found = new ViewEngineResult(new WrappedView(found.View, viewName, isPartial: false), this);
}
return found;
}

public void ReleaseView(ControllerContext controllerContext, IView view)
{
wrapped.ReleaseView(controllerContext, view);
}
}

Get all the details on how to (more) automatically instrument your code with the MiniProfiler (or perhaps, the MiniInstrumentor?) over on Sam's Blog.

Enjoy!

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.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.