Scott Hanselman

Back to Basics: Assert your assumptions and diff your source code

March 13, '14 Comments [20] Posted in ASP.NET | Back to Basics
Sponsored By

I've done a whole series of "Back to Basics" posts that I encourage you to check out. Sometimes I'll do a post as a result of a reader emailing me for help and this is one such post.

A person emailed me with an ASP.NET app was behaving differently on his computer vs. another developer's computer.

On his machine when he hit a protected page foo.aspx?returnurl=http://mymachine.domain.com

he would get a FORM element like this:

<form action="foo.aspx?returnurl=http://mymachine.domain.com">

but on everyone else's machines their HTML was:

<form action="foo.aspx">

They debugging and were frustrated and eventually reached out. They said:

1. there's nothing going on in the aspx of login.aspx that would append the querystring.

2. there's nothing going on in the code-behind of the aspx that manipulates Form.Action or messes with the Page.Render in any way.

So, I'm stumped, because the querystring is included on my machine, but not on others. I've tried comparing IIS components, web.config differences, application pool runtime type, machine.config differences, possible differences in Modules for IIS (IISrewrite), but nothing is giving me love. 

I suggested that they assert assumptions and start diffing everything. You can see in the last paragraph that they're comparing stuff but I think you really have to diff everything.

When something "works here but not there" my answer is always, what has changed? What's different? If the answer is "nothing is different" I'm just gonna say it again:

"What's different?"

What are some things we can check?

  • Code
    • Do you know what's on disk?
    • Do you know what ended up in memory? These are different things.
  • Configuration
    • There's local and machine-wide config to check
  • Network Traffic
    • This is often overlooked. The Internet is not a black box, but you'd be surprised how few people hook up a packet sniffer or even just Fiddler to look at HTTP traffic.
    • I've talked to developers who have said "well, that's under SSL so I can't see it." Oh, my friend, if you only knew.

I had them do a sniff and see if there was a difference in HTTP traffic. My assumption was that the HTTP_REFERER HTTP header was different and there was some code that was causing the page to render differently.

We went back and forth over a few days and my reader became frustrated and just added this line in their app's Page_Load:

this.Form.Action = Request.Url.ToString();

Here they are basically reasserting the Form action by pulling it from the URL. It's gross and it's a hack. It's a Band-Aid on Cancer.

They then started looking at the source for ASP.NET proper and then decided to disassemble the code that was running on the other person's machine. They then started to assert their assumptions.

Is the code running what's on disk? For a compiled language, do the binaries reflect the source?

They looked in Temporary ASP.NET files at the compiled ASPX markup pages and found this.

//ExternalSource("D:\WebApplications\Foo\login.aspx",27)
__ctrl.Method = "post";

//ExternalSource("D:\WebApplications\Foo\login.aspx",27)
__ctrl.Action = "login.aspx";

What? Why is someone setting the FORM Action manually? And there's a line number.

They had diff compared all the source code but not the markup/views/html.

Their markup:

<form id="Form1" method="post" runat="server">

Other person's markup:

<form id="Form1" method="post" runat="server" action="Login.aspx">

The other person had hard-coded the action in their source markup. They'd been diffing everything but the markup.

When you are comparing two code-bases, make sure to compare everything or you might just lose a day or two like this person.

Thanks to my reader for sharing this and letting me in on this debugging adventure.

Related Links:


Sponsor: Big thanks to Red Gate for sponsoring the blog feed this week. Check out the Free Starter Edition of their release management tool! Deploy your SQL Server databases, .NET apps and services in a single, repeatable process with Red Gate’s Deployment Manager. Get started now with the free Starter Edition.

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
Thursday, 13 March 2014 22:12:39 UTC
These kinds of snags sometimes can drive you nuts. Then remember:

  • All computers are in theory digital.

  • The compiler is right, your team is wrong. (Actually, one time it was the other way around. MT+Pascal compiled wrong, this was in 1982.)

  • It helps to read Sherlock Holmes: When you have eliminated the impossible, whatever remains, however improbable, must be the truth.

Friday, 14 March 2014 00:03:38 UTC
I would just like to mention git bisect.

It can be a little bit daunting at first, but it is amazing for finding bugs like this that are in your source control history.
Friday, 14 March 2014 08:13:53 UTC
How about doing a "back to basics" for us dumb windows forms developers who want to transition to web development?

I'm about to start a new winforms project that I know in my heart of hearts should be a web application running in Azure. I did some research and was overwhelmed with "useful" information. So much so that I just plain gave up - I don't have enough time to sort out good from bad and deal with the contradictions - I have software to deliver.

I have resisted web delopment for many years because, as fast as I started on one technology another one came along to 'enhance' it (can we all say dot-j-s?). So many times I went back to winforms because it produces good responsive code that just works. I think web is almost there now, but getting started with a real project that I know I have to deploy is a major wall to climb.

I can find loads of tutorials on ASP development (or should that be MVC now) and loads of descriptions of why Azure is brilliant. Nothing that walks me through getting from opening a new blank VS project to deploying it in a production Azure environment (including the web server management basics and security basics).

Sadly, as the only developer in the company, I don't have access to an IT department or an expert... I am the expert!

Now, this is what I call "back to basics".
Friday, 14 March 2014 08:21:58 UTC
On Diffing - I've found that using WinMerge to do a directory comparison is the easiest way to compare lots of stuff. Great tool.
Friday, 14 March 2014 08:39:18 UTC
and that, kids, is why we use source control ...
Franky
Friday, 14 March 2014 08:47:44 UTC
Time to big-up BeyondCompare - possibly the easiest-to-justify-paying-$30-for piece of software ever.
It is powerful, intuitive and just plain works, which is why it's constantly being used on all of my machines. I paid for my own personal copy, then convinced everybody at the office to use it too - we wouldn't be without it now.
Bob Armour
Friday, 14 March 2014 08:59:25 UTC
I wanted to recommend WinMerge but as I have been beaten to it, I will have to second it ;) The interface isnt as pretty as GitHub for Windows or Team Explorer but to compare to projects its awesome. Select the two folders to compare and click go, you can then filter on types and see the differences by simply clicking on the file. Simples
Lee Cooper
Friday, 14 March 2014 09:17:29 UTC
Steve Barnett, I feel your pain :( I've been mostly server side for about 7 years now, and am so incredibly behind the curve on Web UIs it's not funny. I know the "where to start" problem very well.

However this popped up in my RSS feed the other day, I'm going to try working through it http://msdn.microsoft.com/en-us/magazine/dn605877.aspx
Binary Worrier
Friday, 14 March 2014 09:41:58 UTC
What's up with all this manual diffing? This sounds like something that could have been very quickly resolved by running "git diff" against the affected branch and one known to work.
Friday, 14 March 2014 11:25:47 UTC
Another vote for WinMerge. It's free, it's colourized, it's great!
Friday, 14 March 2014 11:46:14 UTC
Thanks Binary Worrier, a useful link.

I've actually done some ASP work in a previous job where the learning philosophy was "just get on with it and ask when you're stuck". I managed to impress a few people with what I produced but never felt satisfied with the results myself. Since then I've created a couple of test applications that ran fine on my local machine.

That's where a lot of developers seem to stop though. I want more. I want to know what I need to get from MS to get an Azure site (that's the easy bit - I think). I also want/need to know what I need to do to secure and administer the site, how to upload my application to it and get it running. What I need to do to administer any database I need. What I need to do to refresh my application when I find the inevitable "feature" that needs "enhancing".

A lot of people see these as operations issues, but I feel I will write better applications if I have to deal with these issues too. This tends to be where the "education" become thin on the ground for complete beginners.
Friday, 14 March 2014 12:31:14 UTC
Another vote for BeyondCompare - it's been a tool I use and love everyday. Not only text, but folder compares and DATA compares! And very powerful command line ops too.
RedLineTire
Friday, 14 March 2014 14:03:59 UTC
It is just strange for me that your reader did not check form tags on markup. It will be probably second place where I would search for error like that. Also did your reader even use source control?
dejan
Friday, 14 March 2014 14:25:11 UTC
A great (recent) demo about azure:
Worlds greatest azure demo

André Cardoso
Friday, 14 March 2014 15:51:59 UTC
@dejan - this blog post is shared as a cautionary tale of what not to skip, to avoid wasting your own and other's time. Yes, the reader (me) does use source control.

All - thanks for the suggestions on what diff tools to use. I personally use BeyondCompare . Need a JSON compare for BeyondCompare? I wrote that... http://www.scootersoftware.com/vbulletin/showthread.php?t=11878&highlight=json.

The important point here is to *use* the diff tool first and use it *correctly*. Don't assume that there are no changes, because there most likely are.

I went too far into the deep end of "what's different" too quickly. The difference was in the surface level, in the aspx file, not in the bowels of the runtime.

The moral of this story is: Keep Calm and Diff.
Friday, 14 March 2014 17:27:28 UTC
dejan and Jeremy - I think also that things like this can come up in merge between development and production. Production isn't somewhere you can always run gif diff on. Sometimes well-meaning (but wrong) employees mess around on production servers, so this turns into a configuration management issue.
Saturday, 15 March 2014 17:25:49 UTC
I guess I fail to see how this is an example of a real problem. Proper use of source control would make this problem simple--you check the version tree of one code branch versus the other. And am I the only one who thinks it's slightly ridiculous that the markup file wasn't even looked at until all the other things? What's the point of being a web developer if you don't look at the web part of your code?

Hindsight is of course 20/20, but I guess the example seems almost too basic. As a web developer, this makes me cringe to hear about other web developers missing something so seemingly trivial.
Ross
Monday, 17 March 2014 20:42:12 UTC
I recently went through the pain of a similar process. Having targetFramework="4.5" in the httpRuntime attribute in the web.config changes the length of the cookie value preventing single sign on. Who would have thought? I wrote a blog post about this little adventure.
http://codeimo.com/2014/03/tale-of-forms-authentication-single-sign-on-and-the-mystery-of-differing-cookie-lengths/
Wednesday, 19 March 2014 21:17:44 UTC
"even just Fiddler to look at HTTP traffic"

I tried that once. Got in trouble with the ISO (Information Security Officer) - he thought it was a hacker tool.
Thursday, 20 March 2014 19:35:10 UTC
@Phil -

I had a similar issue with our app.
<httpRuntime maxRequestLength="..." executionTimeout="..." /> in app A issuing cookie.

My application consuming the cookie was:
<httpRuntime targetFramework="4.5" />

Same server, so same version .net installed.

I was able to solve the incompatibility by adding this to the <system.web>/<machineKey> element
compatibilityMode="Framework20SP2"

Additional awesome insight here:
http://blogs.msdn.com/b/webdev/archive/2012/11/19/all-about-httpruntime-targetframework.aspx
Comments are closed.

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