Scott Hanselman

Hanselminutes Podcast 241 - The MVVM Pattern with Laurent Bugnion

November 18, 2010 Comment on this post [2] Posted in Open Source | Podcast | Silverlight | WPF
Sponsored By

Scott talks to Laurent Bugnion about the often misunderstood Model-View-ViewModel (MVVM) pattern. What's the different between this pattern and MVC? Can I use this pattern for Silverlight, WPF and Windows Phone 7, and what Open Source projects can support this pattern?

Links from the Show

NOTE: If you want to download our complete archives as a feed - that's all 241 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET AJAX,MVC,Silverlight,Windows Forms and WPF. Enjoy developer tools like .NET Reporting, ORM, Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

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

Hanselminutes Podcast 240 - Developing Indie Games for Xbox 360 and XNA with George Clingerman

November 18, 2010 Comment on this post [2] Posted in Gaming | Learning .NET | Podcast
Sponsored By

Kissy Poo Xbox Live Indie Game for Kids This week Scott talks to George Clingerman, a member of the Independent Xbox Game Development Community (Indie Games) who also runs http://www.xnadevelopment.com. George is a business developer by day and a game developer by night, using C# and managed code in both instances. How does this all work and how can you develop and sell your own games?

Links from the Show

NOTE: If you want to download our complete archives as a feed - that's all 240 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET AJAX,MVC,Silverlight,Windows Forms and WPF. Enjoy developer tools like .NET Reporting, ORM, Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

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

Hanselminutes Podcast 239 - Creative Outlets with Rob Conery

November 18, 2010 Comment on this post [0] Posted in Podcast
Sponsored By

devlifeglassesRob Conery joins Scott this week as the they talk about their new (and very different) podcast "This Developer's Life." Why does Rob feel the need to create? What's the process? How does one create their own podcast and what are some tips for not just success, but feeling good after!

NOTE: If you want to download our complete archives as a feed - that's all 239 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET AJAX,MVC,Silverlight,Windows Forms and WPF. Enjoy developer tools like .NET Reporting, ORM, Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

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

Hanselminutes Podcast 238 - ASP.NET MVC 3 RC and NuGet Package Management with Phil Haack

November 18, 2010 Comment on this post [0] Posted in ASP.NET | ASP.NET MVC | Podcast
Sponsored By

image It's PDC week and Scott's on campus with Phil Haack talking about ASP.NET MVC 3 RC and the NuPack NuGet Package Manager. Get ASP.NET MVC 3 RC now! Also, check out my PDC 2010 presentation on both topics!

NOTE: If you want to download our complete archives as a feed - that's all 238 shows, subscribe to the Complete MP3 Feed here.

Also, please do take a moment and review the show on iTunes.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface and developer tools, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET AJAX,MVC,Silverlight,Windows Forms and WPF. Enjoy developer tools like .NET Reporting, ORM, Automated Testing Tools, Agile Project Management Tools, and Content Management Solution. And now you can increase your productivity with JustCode, Telerik’s new productivity tool for code analysis and refactoring. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

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 Better ASP.NET MVC Mobile Device Capabilities ViewEngine

November 16, 2010 Comment on this post [37] Posted in ASP.NET | ASP.NET MVC | Mobile | Open Source
Sponsored By

UPDATE from 2011: These View Engines have a subtle release mode caching bug. Peter Mourfield and I have released a better MobileViewEngine for ASP.NET MVC 3 that is closer to what MVC 4 will look like. The updated blog post with the new MobileViewEngine is here.

In March of 2009 I spoke at Mix 09, Microsoft's Web Conference and presented a number of ASP.NET MVC features. I extended the NerdDinner Sample with a naive implementation of what I called a MobileCapableWebFormViewEngine. Here's the basic implementation. Don't use this, it's broken.

public class MobileCapableWebFormViewEngine : WebFormViewEngine
{
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult result = null;
var request = controllerContext.HttpContext.Request;

// Avoid unnecessary checks if this device isn't suspected to be a mobile device
if (request.Browser.IsMobileDevice)
{
result = base.FindView(controllerContext, "Mobile/" + viewName, masterName, useCache);
}

//Fall back to desktop view if no other view has been selected
if (result == null || result.View == null)
{
result = base.FindView(controllerContext, viewName, masterName, useCache);
}

return result;
}
}

This sample was never meant to be official anything, just show possibilities, but a lot of folks built on top the general idea. However, as reader Michael Baden Roufa (along with Will Creedle and Paulie Srinuan) pointed out to me in email, the logic is wrong. The FindView (and its sibling FindPartialView) method gets called by the ASP.NET MVC framework with useCache=true first, then useCache=false if nothing is found. This little sample view engine, as it is, is dependant on what kind of browser requests a page first because it's using one cache for two kinds of requests. I've noticed this on the NerdDinner site...depending on which device hits the site first, it can get stuck (cached) in a situation where non-mobile pages are being served to iPhones and mobile browsers.

I'll write a much longer post in a few days about how one goes from Broken, to Complex, Refactors, then finally gets to a Simpler Design. Here's how you'd use this code today. This is an example usage within Global.asax. You'd change it depending on the devices you'd care about.

void Application_Start()
{
RegisterRoutes(RouteTable.Routes);

ViewEngines.Engines.Clear();
ViewEngines.Engines.AddIPhone<WebFormViewEngine>();
ViewEngines.Engines.AddMobile<WebFormViewEngine>("blackberry", "Mobile/BlackBerry");
ViewEngines.Engines.AddMobile<WebFormViewEngine>(c => c.UserAgentContains("SomethingCustom"), "Mobile/SomethingCustom");
ViewEngines.Engines.AddGenericMobile<WebFormViewEngine>();
ViewEngines.Engines.Add(new WebFormViewEngine());
}

You're probably familiar with the concept of ViewEngines and you have heard, at least around town, that you can add 3rd party View Engines, and even mix them and match them. You can have WebForms Views, Spark Views, and Razor Views all in the same project. Rather than deriving from WebFormsViewEngine (or now in ASP.NET MVC 3, RazorViewEngine) and making a super-smart ViewEngine that has too many responsibilities (remember the Single Responsibility Principle), instead I talked to a bunch of folks and realized that I didn't want a smart ViewEngine with knowledge of a lot of devices. ASP.NET MVC already has the notion of an ordered list of ViewEngines.

Since I was on campus this week visiting, I talked to lots of folks like Levi Broderick, Dmitry Robsman, Damian Edwards, Brad Wilson, Marcin Dobosz and more. That's what I really miss while working from Oregon...the wandering around and brainstorming.

Anyway, adding some extension methods to ViewEngineCollection for standard options, while creating a CustomMobileViewEngine as a base to build on makes for a more flexible solution and cleaner code. The example above is the "everything example." You've got an iPhone View, a generic Mobile View, a BlackBerry View based on UserAgent, as well as a Custom View using a custom Lambda for some custom device, then finally the desktop view, which in this case is the WebFormViewEngine.

If you just wanted a Desktop Site and an iPhone site with Razor you'd do this. Note that the ordering is important. View folders are checked in the order they are listed here, each falling to the next until a View is found.

ViewEngines.Engines.Clear();
ViewEngines.Engines.AddIPhone<RazorViewEngine>();
ViewEngines.Engines.AddGenericMobile<RazorViewEngine>();
ViewEngines.Engines.Add(new RazorViewEngine());

Mixing WebForms Views and Razor Views next to Desktop Views and Mobile Views

You can also mix and match. A common scenario might be that you already have a nice WebFormViewEngine ASP.NET MVC site, but you'd like to add a mobile site and start using Razor at the same time for just those mobile views.

ViewEngines.Engines.Clear();
ViewEngines.Engines.AddGenericMobile<RazorViewEngine>();
ViewEngines.Engines.Add(new WebFormViewEngine());

So where are these Views to be found? Let's look at a more custom example. Given this example above, if I am in the HomeController's Index method and it calls View(), we'll look first for ~/Views/Home/Mobile/Index.cshtml, then ~/Views/Home/Index.aspx.

I could also add a custom UserAgent string to look for, with its own folder, with one line:

ViewEngines.Engines.Clear();
ViewEngines.Engines.AddMobile<WebFormViewEngine>("blackberry", "Mobile/BlackBerry");
ViewEngines.Engines.AddGenericMobile<RazorViewEngine>();
ViewEngines.Engines.Add(new RazorViewEngine());

Now if I called the HomeController's Index's method looking for the Index view, we'll look first for ~/Views/Home/Mobile/Blackberry/Index.aspx, then ~/Views/Home/Mobile/Index.cshtml, and finally ~/Views/Home/Index.aspx. However, we'll only be checking Mobile if it's a mobile device (per the Browser Capabilities object) and only checking the BlackBerry folder if the UserAgent contains "blackberry."

Sometimes, though, you'll want more complex custom "is this the right device" logic. Then you can pass in a lambda using whatever reasoning makes you happy, be it UserAgents, cookies, headers, whatever.

ViewEngines.Engines.Clear();
ViewEngines.Engines.AddIPhone<WebFormViewEngine>();
ViewEngines.Engines.AddMobile<WebFormViewEngine>("blackberry", "Mobile/BlackBerry");
ViewEngines.Engines.AddMobile<RazorViewEngine>(c => c.SomeExtensionMethod("SomethingCustom"), "Mobile/SomethingCustom");
ViewEngines.Engines.AddGenericMobile<RazorViewEngine>();
ViewEngines.Engines.Add(new WebFormViewEngine());

Now I've added a new line that digs around the ControllerContext (that's "c") for some information to base my decision on, and if that is true, it'll use the Mobile/SomethingCustom folder for the views. Remember that order matters.

Certainly this is just one way to do things, but it does maximize controller reuse. Not every site can be done like this. Different sites have different flows. You might end up with custom controllers for certain devices or maybe just custom actions. Or, you may need two totally different sites. It depends on your business needs, but it's nice to know the flexibility is here.

CustomMobileViewEngine

To do a hello world example, make a new MVC project (this will work for ASP.NET MVC 2 or ASP.NET MVC 3) and add this class to it (be aware of your namespace.) Again, I'll get this in NuGet soon.

public class CustomMobileViewEngine : IViewEngine
{
public IViewEngine BaseViewEngine { get; private set; }
public Func<ControllerContext, bool> IsTheRightDevice { get; private set; }
public string PathToSearch { get; private set; }

public CustomMobileViewEngine(Func<ControllerContext, bool> isTheRightDevice, string pathToSearch, IViewEngine baseViewEngine)
{
BaseViewEngine = baseViewEngine;
IsTheRightDevice = isTheRightDevice;
PathToSearch = pathToSearch;
}

public ViewEngineResult FindPartialView(ControllerContext context, string viewName, bool useCache)
{
if (IsTheRightDevice(context))
{
return BaseViewEngine.FindPartialView(context, PathToSearch + "/" + viewName, useCache);
}
return new ViewEngineResult(new string[] { }); //we found nothing and we pretend we looked nowhere
}

public ViewEngineResult FindView(ControllerContext context, string viewName, string masterName, bool useCache)
{
if (IsTheRightDevice(context))
{
return BaseViewEngine.FindView(context, PathToSearch + "/" + viewName, masterName, useCache);
}
return new ViewEngineResult(new string[] { }); //we found nothing and we pretend we looked nowhere
}

public void ReleaseView(ControllerContext controllerContext, IView view)
{
throw new NotImplementedException();
}
}

public static class MobileHelpers
{
public static bool UserAgentContains(this ControllerContext c, string agentToFind)
{
return (c.HttpContext.Request.UserAgent.IndexOf(agentToFind, StringComparison.OrdinalIgnoreCase) > 0);
}

public static bool IsMobileDevice(this ControllerContext c)
{
return c.HttpContext.Request.Browser.IsMobileDevice;
}

public static void AddMobile<T>(this ViewEngineCollection ves, Func<ControllerContext, bool> isTheRightDevice, string pathToSearch)
where T : IViewEngine, new()
{
ves.Add(new CustomMobileViewEngine(isTheRightDevice, pathToSearch, new T()));
}

public static void AddMobile<T>(this ViewEngineCollection ves, string userAgentSubstring, string pathToSearch)
where T : IViewEngine, new()
{
ves.Add(new CustomMobileViewEngine(c => c.UserAgentContains(userAgentSubstring), pathToSearch, new T()));
}

public static void AddIPhone<T>(this ViewEngineCollection ves) //specific example helper
where T : IViewEngine, new()
{
ves.Add(new CustomMobileViewEngine(c => c.UserAgentContains("iPhone"), "Mobile/iPhone", new T()));
}

public static void AddGenericMobile<T>(this ViewEngineCollection ves)
where T : IViewEngine, new()
{
ves.Add(new CustomMobileViewEngine(c => c.IsMobileDevice(), "Mobile", new T()));
}
}

Go to your Global.asax.cs (or .vb) as I've showed before, and add maybe these lines to the end of your Application_Start().

ViewEngines.Engines.Clear();
ViewEngines.Engines.AddIPhone<RazorViewEngine>();
ViewEngines.Engines.AddGenericMobile<RazorViewEngine>();
ViewEngines.Engines.Add(new RazorViewEngine());

If you're using ASP.NET MVC 2, or if you simply prefer to, change RazorViewEngine to WebFormViewEngine. Or, mix and match to your taste.

In your Views folder, make ~/Views/Home/Mobile and ~/Views/Home/Mobile/iPhone and copy ~/Views/Home/Index.* to it. Then, open the new Mobile Index and Mobile/iPhone Index and change them. I'm put in "I'm a mobile view" and "I'm an iPhone view" just so I'd know for this hello world example. Like this:

All my Mobile View Folders just so

Next, either get a User Agent Switcher for your browser, or download a fake iPhone Simulator called iBBDemo2 (it's totally fake, but it'll do). Hit the site, and boom, there you go.

My page in a Fake iPhone

Adding iPad is trivial:

ViewEngines.Engines.AddMobile<RazorViewEngine>("iPad", "Mobile/iPad");

As is Windows Phone 7 if you like:

ViewEngines.Engines.AddMobile<RazorViewEngine>("Windows Phone", "Mobile/WP7");

You get the idea.

More to Come

Since that post, the Live.com team in Ireland that released and supported the original Mobile Device Browser File (MDBF) has stopped producing it. The best source for mobile browser device data is WURFL (that was one of the places that MDBF pulled from.)

While I haven't spoken with the 51degrees.mobi folks (yet), they have an ASP.NET module that sucks information from WURFL and populates the Browser Capabilities object. Remember that everyone's requirements are different. You may not need to know everything about every device. Maybe you want to support iPhones and Desktop and that's it. Or, maybe you need to know the screen width and JPEG capabilities of some obscure old Nokia device. Know what you need before you buy into a detection decision or mobile database. We're working on more mobile recommendations and pest practices on the ASP.NET team and I'll continue share everything I know.

I'll be working with my new teammate Steven Sanderson on this template, maybe getting it into NuGet in the short term, and more baked into the framework in the long term. I'll update the NerdDinner sample - older versions for Mobile, and newer versions for MVC3 and mobile. I'll also try to look at jQuery Mobile and some of the nice JavaScript mobile libraries and improve the default templates. I'll also look at adding "opt out" options, so you can hit a site, get a mobile experience, but click a link that says "give me desktop anyway."

For now, it's a much better proof of concept for you to play with, Dear Reader.

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.