Scott Hanselman

Dinner at the Crossroad Mall on 7/7?

July 3, '03 Comments [2] Posted in Web Services | Diabetes
Sponsored By

Hey, I'm going to be up in Seattle for the .NET Users Group on the MSFT Campus on Monday, July 7th.  Anyone want to meet at the Crossroads around 4:45pm-5pm?   It's a good excuse to leave work early (research!)...help me carbo load (not really advised for diabetics) before the talk.  Leave me comments here or email me (link at the bottom).

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

So many mistakes for me to make, so little time...capturing StandardError and StandardOutput

July 2, '03 Comments [1] Posted in Web Services | Bugs
Sponsored By

This struck me as particularly interesting, because it's one of those "doh!" things that is simultaneously completely obvious after the fact but not obvious on a cursory glance if you're not paying attention.

If, in C#/.NET, you wish to spawn a process of CMD.EXE /C SomeBatchFileOrSomeProgram.exe, and you wish to capture both the StandardOutput and the StandardError, well, you need to think.

If you do something like this:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = "test.exe";
p.Start();
string output = p.StandardError.ReadToEnd();
p.WaitForExit();

You'll only get StandardError.  But of course, if you try to ReadToEnd both streams (here's where it's obvious) the first one will of course block if standard error output occurs, since you can't read from standard error until you're done with standard output, etc etc, blah blah, well you get it. 

string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();  

There are lots of code samples around that contain this bug.  Of course, the bug won't happen if your spawned console process doesn't mix standard error and standard output.  But, when you spawn a batch file, certainly it will spawn other processes and who knows. 

This fellow at CodeProject has the right idea, although his sample wasn't created to solve this problem, but rather another.

Process Proc = Process.Start(Info);
   
m_StdOutReader = new RedirOutReader(Proc, Printer, Proc.StandardOutput);
m_StdOutReader.Start();
   
m_StdErrReader = new RedirOutReader(Proc, Printer, Proc.StandardError);

m_StdErrReader.Start();  

He spawns two threads, one to handle standard error and one to handle standard output, which is the alluded-to-and-recommended-but-no-one-wrote-the-sample-cause-it-would-have-been-too-hard solution to this problem. 

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 Content-Disposition Saga: Controlling the suggested file name in the Browser's Save As Dialog

July 1, '03 Comments [0] Posted in ASP.NET | Web Services
Sponsored By

Sometimes when I'm dynamically generating a graphic on the server side, perhaps a chart or graph, or I'm retrieving a check image via Web Services, the user wants to save the time, and I want to control the file name that is suggested in the File|Save As Dialog.  Most often the browser will just recommend the page's file name (the one that was part of the HTTP GET request).  So, how do you control the suggested Save As filename?

UPDATE: Here's how you do it in IE8.

Well, you do and you don't.  There's a HTTP Header called Content-Disposition (case senstitive) that is NOT part of the HTTP standard, but rather it's own Request for Comments, RFC 1806.

HTTP Headers are name values pairs, so they are easily added with the Response object in ASP or ASP.NET You use it like this (the HTTP Headers):

HTTP/1.1 200 OK
<snip>
Content-Disposition: filename=checkimage.jpg
Content-Length: 76127
Content-Type: image/JPEG

Or, if you want to immediately prompt the user with a File Download Box: 

HTTP/1.1 200 OK
<snip>
Content-Disposition: attachment; filename=checkimage.jpg
Content-Length: 76127
Content-Type: image/JPEG

However, Internet Explorer has never really got it right.

Here's a list of gotchas, starting with my own:

  • On IE 6.0, things mostly work, but if you ALSO setup Cache-Control: no-cache, your suggested filename (and type!) will be IGNORED.  A bummer if you have to choose between security and convienence.  Of course, security wins.
  • On IE 4, the attachment option is flaky, see Q182315
  • On IE 5.5, the attachment option is REALLY flaky, see Q267991 and Q279667 and Q281119
  • On IE 5.0, the filename suggested can mangle your filenames, see Q262042 
  • On nearly all versions of IE, including 6.0, sometimes the browser will use the filename in the address bar instead of the Content-Disposition Header, and with IE5.5SP2 you're expected to change the UseCDFileName registry key, see Q303750.  This was fixed with IE6.0SP1.

Also, there are some security issues around Content-Disposition, like suggesting evil names of files to make a careless user overwrite /etc/passwd, etc, that were included in the updated RFC 2183

For classic ASP folks, here are some good code samples around Content-Disposition.

It's a shame that this can't just work as the spec was written, and it's taken 2+ versions of IE to still get it wrong.

Note: Remember, if you want to sniff your own HTTP Headers, do it with class and use Jonas Blunck's iehttpheaders.

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

WSE and Timestamping - TimeZones and Tijuana

June 30, '03 Comments [0] Posted in Web Services | XML | Tools
Sponsored By

A fellow emailed me about some trouble he was having with WSE (Web Services Enhancements) and Timestamp Expiration.  He was getting a SOAP Exception (Timestamp Fault) and figured it was because his machines were in different timezones.  This is what I told him:

This isn’t neccessarily an issue of maturity of the toolkit, it’s simply how TimeStamping (TTL) works on Web Services. Personally, I run my Web Servers on GMT/Universal Time to avoid even thinking about Timezones.  Either way, it’s really about Universal Time (UTC).  When you see a DateTime (when sniffing) in a Created or Expires you’ll notice that they append a “Z” (http://www.w3.org/TR/NOTE-datetime and http://www.learnmobile.net/MobileClient/Tutorials/cfWSE/) that indicates the DateTime is in UTC.  Note: 1994-11-05T08:15:30-05:00 corresponds to November 5, 1994, 8:15:30 am, US Eastern Standard Time. 1994-11-05T13:15:30Z corresponds to the same instant. (note: http://msdn.microsoft.com/webservices/building/wse/default.aspx?pull=/library/en-us/dnglobspec/html/ws-security-addendum.asp#ws-security-addendum__toc17425559 at 5.2.1. Expiration.

 

  • What is your timestamp expiration set to?  5 seconds? 60 seconds?
  • Are the client and server using an NTP server (they need to be at LEAST within 30 seconds of each other or so.
  • What times are you seeing?  (What does the “conversation” look like between the two machines...use ProxyTrace or YATT.)
  • Are the machines (client and server) set to their respective timezones (in Windows Regional Settings)…some people in New York just change the system time and not the zone and the machine thinks it’s in Tijuana.

It’s may not be an issue of hours apart; it’s probably minutes or seconds from UTC.  Timestamping only works when the clocks are set and set well! :)

UPDATE: in classic CarTalk style it turns out it it WAS the TimeZone.  If you don't tell your system WHERE it is, it can't tell you what time UTC is.

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

Nesting Regions in VS.NET 2003

June 26, '03 Comments [2] Posted in Web Services
Sponsored By

Did you know that you can nest #regions in VS.NET?  You can create hierarchies of regions...seems obvious, but it wasn't to me.  Thanks to Rocco for the tip.

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.