Scott Hanselman

Found Video: Social Networking for Developers and Making Your Blog Suck Less

June 21, '10 Comments [21] Posted in Blogging | Speaking
Sponsored By

I was putting together a list of resources for a friend on how to start in programming, and the importance of Social Networking and having an online presence for Developers. I did a talk a while back and there was really bad guerilla video taken. However, in my searching I discovered video of me (scandalous!) at a Microsoft website called Thrive. I had completely forgotten that this talk was recorded. Of course, as it's older, it may be dated in some ways.

The video player on that site is too small, so I've embedded it here and made it big. Also, I've viewed-source and here's links to downloadable video files of both. This video was taken at Devscovery last year, as I recall and the audience was hardcore developers.

Part 1: How to be a better developer through social media

Download "How to be a better developer through social media" media directly here (right click | save as)

Part 2: How to make your blog suck less

Download "How to make your blog suck less" media directly here (right click | save as)

There's newer slides at http://hnsl.mn/bwbslides and I'm considering updating the whole deck and writing an e-book, so watch for that.

Hope these are useful!

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 52 - You keep using that LINQ, I dunna think it means what you think it means.

June 18, '10 Comments [25] Posted in ASP.NET | Data | Learning .NET | LINQ | Source Code
Sponsored By

Remember good developers don't just write source code, they also READ it. You don't just become a great poet by writing lots of poems. Read and absorb as well. Do check out the Source Code category of my blog here, there is (as of today) 15 pages of posts on Source Code you can check out.

Recently my friend Jonathan Carter (OData Dude, my name for him) was working with a partner on some really weird stuff that was happening with a LINQ to SQL query. Remember that every abstraction sometimes leaks and that the whole port of an abstraction is "raise the level" so you don't have to worry about something.

Plumbing is great because it abstracts away water delivery. For all I know, there's a dude with a bucket who runs to my house when I turn on the tap. Doesn't matter to me, as long as I get water. However, sometimes something goes wrong with that dude, and I don't understand what's up with my water. This happened to JC and this partner.

In this example, we're using the AdventureWorks Sample Database to make this point. Here's some sample code the partner sent us to reproduce the weirdness.

protected virtual Customer GetByPrimaryKey(Func<customer, bool> keySelection)
{
AdventureWorksDataContext context = new AdventureWorksDataContext();

return (from r in context.Customers select r).SingleOrDefault(keySelection);
}

[TestMethod]
public void CustomerQuery_Test_01()
{
Customer customer = GetByPrimaryKey(c => c.CustomerID == 2);
}

[TestMethod]
public void CustomerQuery_Test_02()
{
AdventureWorksDataContext context = new AdventureWorksDataContext();
Customer customer = (from r in context.Customers select r).SingleOrDefault(c => c.CustomerID == 2);
}

CustomerQuery_Test_01 calls the GetByPrimaryKey method. That method takes a Func as a parameter. He's actually passing in a lamdba expression into the GetByPrimaryKey function. That makes the method reusable and is the beginning of some nice helper functions for his DAL (Data Access Layer). He's split up the query into two places. Seems reasonable, right?

Well, if you run this in Visual Studio - and in this example, I'll use the Intellitrace feature to see the actual SQL that was executed, although you can also use SQL Profiler - we see:

Wrong SQL in the Watch Window

Here's the query in text:

SELECT [t0].[CustomerID], [t0].[NameStyle], [t0].[Title], 
[t0].[FirstName], [t0].[MiddleName], [t0].[LastName],
[t0].[Suffix], [t0].[CompanyName], [t0].[SalesPerson],
[t0].[EmailAddress], [t0].[Phone], [t0].[PasswordHash],
[t0].[PasswordSalt], [t0].[rowguid], [t0].[ModifiedDate]
FROM [SalesLT].[Customer] AS [t0]

Um, where's the WHERE clause? Will LINQ to SQL kill my pets and cause me to lose my job? Does Microsoft suck? Let's take a look at the second query, called in CustomerQuery_Test_02():

SELECT [t0].[CustomerID], [t0].[NameStyle], [t0].[Title], 
[t0].[FirstName], [t0].[MiddleName], [t0].[LastName],
[t0].[Suffix], [t0].[CompanyName], [t0].[SalesPerson],
[t0].[EmailAddress], [t0].[Phone], [t0].[PasswordHash],
[t0].[PasswordSalt], [t0].[rowguid], [t0].[ModifiedDate]
FROM [SalesLT].[Customer] AS [t0]
WHERE [t0].[CustomerID] = @p0

OK, there it is, but why does the second LINQ query cause a WHERE clause to be emitted but the first doesn't? They look like basically the same code path, just one is broken up.

The first query is clearly returning ALL rows to the caller, which then has to apply the LINQ operators to do the WHERE in memory, on the caller. The second query is using the SQL Server (as it should) to do the filter, then returns WAY less data.

Here's the deal. Remember that LINQ cares about two things, IEnumerable stuff and IQueryable. The first lets you foreach over a collection, and the other includes all sorts of fun stuff that lets you query that stuff. Folks build on top of those with LINQ to SQL, LINQ to XML, LINQ to YoMomma, etc.

When you are working with something that is IQueryable; that is, the source is IQueryable, you need to make sure you are actually usually the operators for an IQueruable, otherwise you might fall back onto an undesirable result, as in this database case with IEnumerable. You don't want to return more data from the database to a caller than is absolutely necessary.

From JC, with emphasis mine:

The IQueryable version of SingleOrDefault, that takes a lambda, actually takes an Expression>, whereas the IEnumerable version, takes a Func. Hence, in the below code, the call to SingleOrDefault, is treating the query as if it was LINQ To Objects, which executes the query via L2S, then performs the SingleOrDefault on the in memory collection. If they changed the signature of GetByPrimaryKey to take an Expression>, it would work as expected.

What's a Func and what's an Expression? A Func<> (pronounced "Funk") represents a generic delegate. Like:

Func<int,int,double> divide=(x,y)=>(double)x/(double)y;
Console.WriteLine(divide(2,3));

And an Expression<> is a function definition that can be compiled and invoked at runtime. Example"

Expression<Func<int,int,double>> divideBody=(x,y)=>(double)x/(double)y;
Func<int,int,double> divide2=divideBody.Compile();
write(divide2(2,3));

So, the partner doesn't want a Func (a Func that takes a customer and returns a bool, they want a compliable Expression with a Func that takes a Customer and returns a bool. I'll have to add "using System.Linq.Expressions;" as well.

protected virtual Customer GetByPrimaryKey(Expression<Func<customer,bool>> keySelection)
{
AdventureWorksDataContext context = new AdventureWorksDataContext();

return (from r in context.Customers select r).SingleOrDefault(keySelection);

}

[TestMethod]
public void CustomerQuery_Test_01()
{
Customer customer = GetByPrimaryKey(c => c.CustomerID == 2);
}

[TestMethod]
public void CustomerQuery_Test_02()
{
AdventureWorksDataContext context = new AdventureWorksDataContext();
Customer customer = (from r in context.Customers select r).SingleOrDefault(c => c.CustomerID == 2);
}

Just changed that one line, so that GetByPrimaryKey takes a Expression> and I get the SQL I expected:

Corrected SQL in the Watch Window

Someone famous once said, "My code has no bugs, it runs exactly as I wrote it."

Layers of Abstraction are tricky, and you should always assert your assumptions and always look at the SQL that gets generated/created/executed by your DAL before you put something into production. Trust no one, except the profiler.

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 217 - MVC Turbine and IoC made easy with Javier Lozano

June 11, '10 Comments [6] Posted in ASP.NET | ASP.NET MVC | IOC | Podcast
Sponsored By

headshot My two-hundred-and-seventeenth podcast is up. Scott talks to Javier Lozano about his open source MVC Turbine project and how it makes Dependency Injection and inversion of control extremely easy. These concepts can be tricky to jump into and usually require custom code in your app. MVC Turbine makes it easy to get up and running in minutes with ASP.NET MVC and IoC.

(Ya, I know, I'm late to post this.)

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Download: MP3 Full Show

Links from the 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.

I want to add a big thanks to Telerik. Without their support, there wouldn't be a Hanselminutes. I hope they, and you, know that. Someone's gotta pay the bandwidth. Thanks also to Carl Franklin for all his support over these last 4 years!

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 Formsand WPF. Enjoy developer tools like .NET reporting, ORM,Automated Testing Tools, TFS, 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 fromTravis 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

Experiments in Wackiness: Allowing percents, angle-brackets, and other naughty things in the ASP.NET/IIS Request URL

June 9, '10 Comments [12] Posted in ASP.NET | ASP.NET MVC | IIS
Sponsored By

Just because you CAN do something doesn't mean you SHOULD. However, it's always nice to do something crazy so that you can better understand a system.

Warning: There is no warranty implied here. I'm loading the gun and showing you where to point it. If you point it at your foot, that's your business. Safety mechanisms exist for a reason and if you're going to to use this tip to just "get an app to work" but you're not sure why it's broken and you're just flipping switches to "get'er done" then step backwards out of the minefield and hug your family. Don't trust user input and don't let users submit unencoded script or markup.

I got a question from a fellow at Webcamps China about why he couldn't put in a URL. He wanted to do something like : http://localhost:39090/Default/%3Cb%3E That's a as in "%3C b %3E" were the %3C is < and %3E is >.

Notice he's asking to put this in the Request Path, the URL, not in the Query String. If I create a quick ASP.NET MVC 2 app (this could be done in WebForms also) and issue http://localhost:39090/Default/%3Cb%3E I get this HTTP Error 400. Notice it's not a standard YSOD, it's a simple error message.

Bad Request - Windows Internet Explorer (2)

This error was caught and issued early in the pipeline, before ASP.NET proper got involved. In this case, I'm using the development web server, but I'd get a similar error from IIS proper.

Now, if I change the URL to use the QueryString instead of the Request Path: http://localhost:11965/Home/Index?id=%3Cb%3E

A potentially dangerous Request.QueryString value was detected from the client (id=b). - Windows Internet Explorer

This was caught in a different place, in ASP.NET managed code, specifically in input validation. I remember when I first used input validation 7 years ago. ;)

If you really know what you're doing and you know WHY you're doing it, you can turn Request Validation off in a number of ways.

However, this is a really bad idea so they've made it harder in ASP.NET 4 and you have to explicitly tell it you want the 2.0 style of request validation this first in the system.web section via requestValidationMode:

Then, if you are using WebForms, you can turn it off totally at the application level in your web.config.

Or, again, if you're using WebForms, you can turn it off for one page:

<%@ Page validateRequest="false" %> 

If you're using MVC, you turn it off Input Validation using the [ValidateInput(false)] attribute on a class or a method.

In this case if I turn it off on my method, it works and I can pass the encoded as %3Cb%3E directly in the Query String, but STILL not in the Request Path as that's a different path through the server.

So, with request validation in 2.0 mode and also explicitly turned off on my method:

Now here I'm really telling you about the minefield. Best way to not get killed in a minefield is to avoid it all together, but, since you insist...

Stefan from the ASP.NET team says:

  • By default the "requestPathInvalidChars" attribute contains seven characters considered invalid (the less than and greater than signs as well as the ampersand are encoded since configuration is an Xml file). Those are on the httpRuntime element, and the attribute is requestPathInvalidCharacters="<,>,*,%,:,&"

So, then I might be able to change


requestPathInvalidCharacters="<,>,*,%,:,&,\"
/>

to this, removing the <, >, and %.


requestPathInvalidCharacters="*,:,&,\"
/>

But, remember that a % is a special thing used in URL Encoding (percent encoding) and you can say things that are encoded correctly like %3B or things that aren't like %ZZ. So it depends on the semantics you want. What do you intend for a % to mean? From Stefan:

Note though that the “%” character has special meaning as the beginning of a Url-encoded character sequence.  You may run into a problem with IIS rejecting the Url depending on what comes after the % sign.  For example if the inbound Url is:

http://whatever/blah%2512

IIS7 will complain because after it does a Url-decode the Url will look like:

http://whatever/blah%12

Which will trigger the double-decode detection alert since the Url will mutate again if it is Url-decoded a second time.

To suppress that error you need to  add the following to configuration as well. requestFiltering allowDoubleEscaping="true"





However, at this point, you're turning off all sorts of things, and are in danger of making URLs that just shouldn't be. ;) You may also have a latent canonicalization bug floating around in your code if you head down this road.

But does it work? It doesn't work under Visual Studio Development Web Server as the system.webServer section only applies to IIS7. If I deploy my ASP.NET MVC application to IIS, it starts to work as I get into my controller action, but then as I return the ViewResult via "return View()" it fails deep inside of ASP.NET proper as the WebFormsViewEngine's ViewPage implementation of RenderView() ends up calling Server.Execute which calls HttpRequest.MapPath. MapPath assumes there's an underlying file and calls InternalSecurityPermissions.PathDiscovery().Demand(). This contains a FileIOPermisson which checks for illegal characters. Since you can't have a file that contains a < or >, it fails. Bummer.

System.IO.Path.CheckInvalidPathChars(String path) +142
System.Security.Permissions.FileIOPermission.HasIllegalCharacters(String[] str) +97
System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList) +96
System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList) +38
System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path) +92
System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping) +639
System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +195
System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +94
System.Web.Mvc.ViewPage.RenderView(ViewContext viewContext) +403
...blah blah...
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371

Is there a way to tell the system to "relax?" I mean, seriously, not every URL maps to a file system. If only there were an attribute called relaxedUrlToFileSystemMapping="true". ;)

Oy, if you're not afraid now, be afraid. If you're made it that far, again, you're on your own, turning safeties off, yada yada, mercy on your soul, etc.


requestPathInvalidCharacters="*,:,&,\"
relaxedUrlToFileSystemMapping="true"
/>

While we're in here, note that in ASP.NET 4 you can also change allowed path and queryString lengths:

At this point the only thing that is saving us is the list of characters in requestPathInvalidCharacters. For example, if I try to sneak a %3A by, it won't work as that's a colon (:) and it's in the list. Issuing http://localhost:11965/Home/Index?id=%3A gives me this error "A potentially dangerous Request.Path value was detected from the client (:)." I find it slightly funny that they output the offending evil character. Don't look directly at it! :)

A potentially dangerous Request.Path value was detected from the client (). - Windows Internet Explorer

But still, at this point, now I CAN do this URL: http://localhost:11965/Home/Index/%3Cb%3E

Home Page - Windows Internet Explorer

And I'm saved, finally, by the new HtmlEncoding syntax <%: rather than <%=.

The <%: mystring %>syntax in ASP.NET 4 is equivalent to <%= Server.HtmlEncode (mystring) %>and since it's the default, my UrlEncoded was HtmlEncoded on the way back out.

After ALL this effort to get crazy stuff in the Request Path, it's worth mentioning that simply keeping the values as a part of the Query String (remember WAY back at the beginning of this post?) is easier, cleaner, more flexible, and more secure.

Enjoy, take care, and please don't point that at me.

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 Best Visual Studio 2010 Productivity Power Tools, Power Commands and Extensions

June 9, '10 Comments [33] Posted in VS2010
Sponsored By

One of the things I'm digging about VS2010 is its extensibility model. I'm collecting add-ins in VS like I collect Add-Ins in FireFox. Here's my current of the best Visual Studio 2010 Extensions I'm using.


Visual Studio Color Theme Editor

I've blogged before about the Visual Studio Color Theme Editor. It's great and lets you make VS look like whatever OS you want. Some crazy people try to make Visual Studio 2010 look like Visual Studio 2008! ;)


PowerCommands for Visual Studio 2010

This crazy add-in adds 25 additional commands to Visual Studio! It's a collection of really convenient little improvements like Open Containing Folder and Open Command Prompt. But it's also subtle things like Undo Close that will reopen the most recent tab with the cursor just where it was. There's a lot of Copy/Paste improvements, letting you copy and paste a whole class, or copy and paste references between projects. It even adds "Format Document on Save" that will tidy up your whitespace every time you save your document. Lovely.

PowerCommandsPreview


Visual Studio 2010 Pro Power Tools

Where PowerCommands adds lots of little commands in subtle ways, Pro Power Tools changes UI things in much bigger ways.

image

Two of the big changes are the "Document Well" that changes how tabs behave. It'll color tabs based on what project they came from, which is nice for large solutions. It also introduces optional tab recycling that will close old tabs as you open new ones. If you prefer a pile of tabs, you can get multiple rows or columns of tabs.

You can also Highlight Current Line, nice for large monitors. It adds HTML Copy that puts code in the clipboard as in the HTML format if if you like, but most of all, it adds a new Searchable Add Reference Dialog. Magic.

New Add Reference Dialog


CodeCompare

I'm a fan of BeyondCompare from Scooter Software, but I like integrated stuff as well. CodeCompare is a free Diff tool that runs inside VS itself. It's nice because it's using the VS editor so it has the features you're used to like Ctrl-Scroll to change the font sizes. I wish the two panes changed sizes in sync though, and I've seen one or two crashes. Still, an excellent free compare tool, and I like that I can drag the second file in.

Diff Tool


tangible T4 Editor

T4 (Text Template Transformation Toolkit) Code Generation is Visual Studio's best kept secret. It's built in and it's yummy. However, there's no syntax highlighting and opening .tt files in Visual Studio directly is a smidge scary, as it's hard to tell what's code generating code and what's the code you're generating. With the free tangibile T4 editor you get coloring and Intellisense.

T4MVC.tt - Microsoft Visual Studio (2)

What are your favorites, 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 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.