Scott Hanselman

Hanselminutes Podcast 141 - Coding4Fun with Dan Fernandez and Brian Peek - Wiimotes and YouTube

December 5, '08 Comments [1] Posted in Coding4Fun | Podcast
Sponsored By

My one-hundred-and-forty-first podcast is up. I talk with Dan and Brian as they turn the successful Coding4Fun blog into a book. Brian shares how to interface with the Nintendo Wii's Wiimote, and Dan tells us how to download and convert YouTube videos in one click.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

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, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. 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)

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

South Africa 2008

December 5, '08 Comments [29] Posted in Africa
Sponsored By

Mount KilimanjaroWe try to go to Africa every year if we can. We went there to get married and negotiate lobola. We took our first son there to meet his Grandmother, and now we head back to introduce Son #2 to Gogo.

We're all packed and the house is safe in the hands of the house-sitter. We've got about 25 hours of travel ahead of us with a 1 year old and a 3 year old in tow.

If I'm connected at all on this trip, it'll be to blog about our travels, so temporarily, this blog will turn into an Africa Travel Blog, as it has every year (or every other year) in December, so be warned. If you're not interested (as Jeff is not) in such gripping topics as Black Hair, "Waiting for Death's Sweet Release" or Finding a Fundi, then I'll see you in January. If I get a chance, we'll podcast from the other side of the world as well.

One other thing, I'll be stopping by two User Groups while ekhaya, first on the 8th at 6:30pm in Gauteng in Johannesburg, South Africa:

When: 8th December 2008 18:30 - 20:30
Venue: Microsoft Auditorium 2, Bryanston (
directions)
Topic: Probably MVC and very open Q&A - Vote here.
RSVP: Please RSVP including your full name as Microsoft security now requires this upfront.

Then in Cape Town on the 17th at 1:00pm in Mowbray:

When: 17th December 2008 13:00 (sharp) (yes, that's 1pm)
Venue: Microsoft Cape Town -  Golf Park 3, Engen House, Raapenberg Road, Mowbray

Topic: "Building a Real Website with ASP.NET MVC: Suffering and Pain and Joy" and (very) open Q&A

RSVP: Please RSVP including your full name as Microsoft security now requires this upfront, at hilton at giesenow.com or at http://dotnet.org.za/sadevelopercapetownevents/

Please feel free to spread the word if you're in RSA, but remember that RSVP'ing is needed. See you there!

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 140 - Rob Conery learns about Domain Driven Design

December 4, '08 Comments [7] Posted in Podcast | Programming
Sponsored By

My one-hundred-and-fortieth podcast is up. Neither I nor Rob Conery are experts in DDD (Domain Driven Design.) We hear a lot about DDD, but we hear very "Zen-like" and "soft" terms. As concrete (or fairly so) thinkers, Rob and Scott try to get our tiny minds around DDD. Is it a fad? A religion? Some kind of software design cult? Rob Conery has decided to learn for himself, and I join him for the trip in this episode. We likely accomplished nothing, but we've taken the first step.

The premise of domain-driven design is two-fold:

  • For most software projects, the primary focus should be on the domain and domain logic; and
  • Complex domain designs should be based on a model.

Also, check out Eric Evans on .NET Rocks!

Subscribe: Subscribe to HanselminutesSubscribe to my Podcast in iTunes

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, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. 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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 139 - Moonlight (Silverlight on Linux with Mono) with Miguel de Icaza and Joseph Hill

December 4, '08 Comments [0] Posted in Open Source | Podcast | Silverlight
Sponsored By

Mono Project Logo My one-hundred-and-thirty-ninth podcast is up. Scott chats with with Miguel de Icaza and Joseph Hill, the folks behind Moonlight. It's Silverlight on Linux with Mono and it's Open Source!

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

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, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. 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?

Technorati Tags: ,,,

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Weekly Source Code 38 - ASP.NET MVC Beta Obscurity - ModelState.IsValid is False because ModelBinder pulls values from RouteData

December 4, '08 Comments [18] Posted in ASP.NET | ASP.NET MVC | Source Code
Sponsored By

I found a bug in an application I'm working on. I couldn't decide if it's a bug in the ASP.NET MVC Framework or a feature. I knew this, however. Both their code and my code runs exactly as it was written. ;)

First, the behavior I'm seeing, then a pile of unnecessary technical context because I like to hear myself talk, then my conclusion. Regardless, it's great fun!

UPDATE: I've been promptly teased/beaten by the MVC team, as they pointed out, pointedly, is the same behavior pointed out by Ayende like 15 years ago. It was prompted fixed/changed, and the new behavior changes the order (listed below) to 3, 1, 2 as I understand it. I hang my head in shame. ;) It's been totally fixed in the Release Candidate, so this post acts only as my own CSI:ASPNETMVC.

The Behavior

My application does CRUD (Create, Read, Update, Delete) on Dinners. When you are entering a new Dinner object, you fill out a form and POST your HTML form.

We take in the Dinner and save it (I've removed goo for clarity):

[AcceptVerbs(HttpVerbs.Post)]
[Authorize]
public ActionResult New([Bind(Prefix = "")]Dinner item)
{
if (ModelState.IsValid)
{
item.UserName = User.Identity.Name;
_dinnerRepository.Add(item);
_dinnerRepository.Save();
TempData["Message"] = item.Title + " Created";
return RedirectToAction("List");
}
}

The behavior I'm seeing is that ModelState.IsValid is ALWAYS false.

Note at this point that I'm not clever enough to go digging into the ModelState object for exactly why. More on my stupidity later. ;)

The Context

The Form POST looks like this (RAW HTTP):

Title=Foo&EventDate=2008-12-10&EventTime=21%3A50&Description=Bar&HostedBy=shanselman&LocationName=SUBWAY&MapString=1050+SW+Baseline+St+Ste+A1%2C+Hillsboro%2C+OR&ContactPhone=%28503%29+601-0307&LocationLatitude=45.519978&LocationLongitude=-123.001934

See how there's a bunch of Name/Value pairs in there? They mostly line up with the names of properties in my class as seen below.

Dinner Class Diagram

However, note that ID isn't in the Form POST. It's not there because it's an identity, and it'll be created when we save the Dinner to the database.

The New() method takes a Dinner as a parameter. That Dinner is create by the system because using the DefaultModelBinder. That binder looks at the values in the HTTP POST and tries to line them up with the properties on the object. Notice that there's no "ID" in the Form POST. Why is ModelState.IsValid false?

If I look in the ModelState.Values, I can see that the first value says "A value is required." ModelState.Keys tells me that's "ID" and that "" was passed in.

Watch Window showing error in ModelState.Values

Where did MVC get an ID from and why is it ""? I don't need an ID, I'm in the middle of making a Dinner, not editing one.

Well, it turns out that the DefaultValueProvider, the thing that, ahem, provides values, to the DefaultModelBinder looks in a few places for its values. From the source on CodePlex, note the nice comments:

public virtual ValueProviderResult GetValue(string name) {
if (String.IsNullOrEmpty(name)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}

// Try to get a value for the parameter. We use this order of precedence:

// 1. Values from the RouteData (could be from the typed-in URL or from the route's default values)

// 2. URI query string

// 3. Request form submission (should be culture-aware)


object rawValue = null;
CultureInfo culture = CultureInfo.InvariantCulture;
string attemptedValue = null;

if (ControllerContext.RouteData != null && ControllerContext.RouteData.Values.TryGetValue(name, out rawValue)) {
attemptedValue = Convert.ToString(rawValue, CultureInfo.InvariantCulture);
}
else {
HttpRequestBase request = ControllerContext.HttpContext.Request;
if (request != null) {
if (request.QueryString != null) {
rawValue = request.QueryString.GetValues(name);
attemptedValue = request.QueryString[name];
}
if (rawValue == null && request.Form != null) {
culture = CultureInfo.CurrentCulture;
rawValue = request.Form.GetValues(name);
attemptedValue = request.Form[name];
}
}
}

return (rawValue != null) ? new ValueProviderResult(rawValue, attemptedValue, culture) : null;
}

Seems that while I assumed that the Form POST was the only place that a Model Binder would go looking, in fact, it looks in three places:

  1. Values from the RouteData
  2. URI query string
  3. Request form submission (should be culture-aware)

The emphasis is mine. At this point I know I'm not seeing a bug, but rather an uncomfortable side-effect of my overly generic naming. I created an ID property on Dinner, but is also have the default route in my Global.asax.cs:

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "List", id = "" } // Parameter defaults
);

Note the default value for ID. This can be confirmed in the debugger at the same breakpoint I used before. The RouteData collection shows an ID name/value pair, where the value is "".

Debuger showing the RouteData object

The DefaultModelBinder saw that an ID was available, but it was set to "", which is different than complete omission. If it wasn't there at all, it wouldn't have been required. If it was set to "A" as in /controller/action/A then I'd have seen a different error of "The value 'A' is invalid." as "A" isn't an int.

The Conclusion

I'm going to change my model to use Dinner.DinnerID instead of Dinner.ID so that there's no reuse of tokens between the Route/URL and the Model's property names. Fun stuff! It was so nice to just check the ASP.NET MVC source code to solve my problem. Kudos also to the ASP.NET MVC team for making the source easy to read.

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 twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

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