home links tools blog about
home

March 18, 2008

Response.TrySkipIisCustomErrors and Error Pages

There are oodles of pages out on teh intarwebs that will tell you how to set up custom error handling for your ASP.NET site. If that's what you're looking for, this post isn't for you. However, if you're looking to see how to take complete control over what your custom error pages do, and how they report back to clients, then read on.

404s with all the Guts and Glory
One great approach is to wire up error handling logic in your Global.asax's Application_Error event. I took this approach and was able to get it to work flawlessly with some 'spoofed' 404s that I recently created on one of my sites (i.e., I'm using tons of url-rewriting and needed to be able to discern when a path looked correct (had the right format), but didn't actually map to something in the Database or on the site - so throwing my own NotFoundExceptions was a great way to redirect to my own custom 404 page).

When I tried this same approach with actual 'errors' though I ran into a massive problem. My root problem in this case is that when I really encounter an exception, I want the HTTP STATUS CODE for the page in question to be a 500. If you use the customErrors configuration in the web.config, that works out as an HTTP 302, and if you're just doing Server.Transfer("myCustom500Page.aspx") from you Global.asax, you end up writing an HTTP 200 - which isn't something you want a robot to encounter when the page is obviously broken.

With my custom 404Handler.aspx page I was able to parse info about the exception being thrown to dynamically generate a helpful HTML page, and then spit out a 404. This was perfect - as it let me handle stupid user errors, as well as potential 'real' problems on the site with some decent markup on a custom error page without sending out an HTTP 200 which will cause the page to be indexed by robots should they happen upon it somehow.

What's Good for the Goose doesn't work for the Gander
But if you try the same thing with a custom error page (by doing Response.StatusCode = 500;) you run into a massive problem. What happens first is that it appears that ASP.NET sees the 500 error, assumes that something is wrong, and will attempt to redirect to your custom 500 page specified in the customErrors section of your web.config. (I'll spare you the story of the joy I had watching my site go into an infinite loop on those requests.)

But even worse than that is that once ASP.NET sees the ResponseCode get set to 500, it will try to hand off processing to the custom error page used by IIS. The pisser is that you can't get around this. I tried ApplicationInstance.CompleteRequest() immediately after setting Response.StatusCode = 500 - but that didn't do it. Neither did trying to override or piggy-back on to my custom error page's OnError (because, obviously, no error is being encountered - though the status code is being set to 500).

ASP.NET 3.5 and IIS7 to the Rescue
Just as I was starting to contemplate stuffing the Exception from Server.GetLastError() into Context.Items[], and then pulling it out in my custom errors page, I thought I'd take a peek at Response in IntelliSense to make sure I wasn't missing anything.

Sure enough, there's a new property that INSTANTLY caught my attention: Response.TrySkipIisCustomErrors. It's brand-new, and only works on IIS7 with ASP.NET 3.5. That, however, happened to be the exact platform that I'm on.

More importantly, it lets me:
a) Capture unhandled exceptions in my Global.asax's Application_Error Event Handler
b) Capture the exact error/exception with Server.GetLastError() (note that you'll want to grab that Exception's .InnerException if the Type is of Type HttpUnhandledException)
c) Programatically let me determine which error page to route to in order to handle the exception (depending upon type/details/etc)
d) Do more processing in the page that handles the error (such as enabling/disabling various error descriptions/panels/etc.)
e) Throw an HTTP 500 (or whatever) without getting my response-stream hijacked by IIS.

In other words, this gives me the best of everything: intelligent and dynamically generated custom error pages, and HTTP response codes that give me the control over robots/indexing that I need.

March 06, 2008

Teaching an Old Dog New Tricks

Imagine my surprise when playing around with the recently released ASP.NET MVC Preview2 bits, and finding that one of my hidden form fields wasn't being mapped on the server because the form field only included an id attribute - and not a name attribute.

In other words, I had rendered markup that looked like this:

<input id="objectId" type="hidden" value="3">

When I really needed this:

<input id="objectId" name="objectId" type="hidden" value="3">

But, that threw me for a bit of a loop. See, I've been spending so much time playing around with client-side stuff (i.e. the DOM) for so many years now that I had begun to think that name didn't mean anything anymore.

In fact, the W3C has effectively depricated the name attribute for HTML/DOM interaction. This I knew.  But that was only part of the problem. Because the W3C still favors the name attribute for HTTP interactions. So, with POSTed forms, you'll want to make sure you use id and name attributes if you plan on doing client side interactions.

At any rate, I found all of this a bit ironic because years ago much of my markup ONLY used the name attribute. Somehow between then and now I managed to forget all of that. So, I'm just glad to see that you can teach this old dog new tricks - even if the old dog is old enough to have forgotten that he knew the tricks once before...

January 01, 2008

ASP.NET's MVC and the Threat of XSS

There's a great discussion going on over at Rob Conery's blog - where he's asking for feedback on how to handle encoding options to prevent XSS when using the new ASP.NET MVC. In my mind this is a BIG deal because of just how well traditional ASP.NET (that's weird to say) has handled the task of squelching XSS in the past. It's also a big deal because I really want the MVC to remain as absolutely 'clean' as possible - as in free from 'magic' and other "we're helping you" type of stuff that addresses 90% of use-cases but shoots experienced web developers in the foot on 'edge cases' surrounding standards support and the likes.

So, since Rob is asking for feedback, I thought I'd provide in the form of a blog post (where I can more easily whip-up my thoughts without having to fight inside of a textbox).

What shapes my thoughts/rationale:
Most people interested in using the MVC are going to be more advanced ASP.NET users (and real-life web developers) that are looking for two key things:
a) Greater control over emitted markup (while still being able to leverage the .NET Framework) and
b) Greater separation of data, presentation, and logic. In other words: less intermingling, and less coupling between those realms. Or, stated differently, less 'magic'.

It's also a no-brainer that MVCs are HIGHLY reliant upon convention (at least initially) - which means that co-opting security practices into the convention should be the best way to attack this issue.

My Preferences for handling XSS Encoding:
1)
Leave the responsibility for encoding entirely up to developers. But make it part of the convention. And provide some decent syntax support that makes it logical and easy. In my mind this would allow the greatest degrees of control and separation - yet still make it possible to achieve good security. (Me, I want ALL THREE options (control, separation, and security) - one or two of the three just isn't good enough.)
2) A slightly less perfect approach would be to Encode everything on the way out - as long as there's a way for developers to turn that off (without too much hassle) in the few cases where they'll actually want to do so. That would be tolerable in my mind as it would let MS feel like they had done their best to protect dumber web developers from shooting themselves in the foot, but wouldn't make the rest of us pay too steep of a price. (I still maintain that any time you try to make something more fool-proof you sadly just end up creating better idiots.)
3) The worst option, in my mind, would be to encode on the way in. That quickly shoots clean separation out of the water, and assumes that you'll only ever be using your input data in another web application - which represents HORRIBLE coupling. I think everyone can see that - even if the argument could be made that you're potentially opening yourself up to a 2nd-Order attack by persisting XSS or SQL Injected code.

That said, I'm certainly LOVING the MVC. It's honestly one of the best things to happen to ASP.NET ever. (I get clean separation, complete markup control, and all the benefits of sitting on top of the ASP.NET and .NET framework - all in one tidy little package.) I also think that the learning curve it presents is significantly less than the jump from say Classic ASP to ASP.NET, but I also think that it will result in developers writing CONSIDERABLY less code to get well-functioning apps up and running. More importantly, I finally feel like Microsoft has addressed real-life web-developer needs with a flexible framework - instead of focusing so intently on creating tools for applications developers to make web applications. In other words, I 'feel' like the focus here is more on web sites than on intranet applications - which is VERY exciting to me as I spend most of my dev energy working on sites instead of clunky/massive/enterprise-y intranet applications. (Though, that said, intranet developers should rejoice as well - as the MVC should make their lives easier too if they're looking for standards-compliant markup and cleaner separation as well as a less-monolithic approach to application testing and maintenance.)

November 30, 2007

Hmmm. Interesting

This looks pretty interesting: ParallelFX for .NET.

I'm too busy at the moment to try and play with it. (That, and there's a part of me that just LOVES asynchronous programming.)

But it's no secret that apps/solutions are going to have to take advantage of multi-core machines in order to see noticeable perf boosts in the future.

Frankly, one of the things that I _love_ about SQL Server is that it has been SMP capable for YEARS. Better yet, that capability is largely hidden from developers. Ideally this ParallelFX CTP is a step in making the same type of SMP benefits available (almost transparently) to .NET developers.

June 15, 2007

Shout Out to Hosted-Projects.com

No, I'm not an actor. No, I don't even play one on TV. I'm also not a paid spokesman for Hosted-Projects.com, but I just needed to give them a shout out for providing such excellent service.

I've posted about them before (back when I did my brief series on products/services that rock), and if you don't remember, they provided hosted Subversion (along with project and bug tracking) at great prices with excellent up-times and speeds.

I'm grand-fathered into one of their older packages (300 MB with three repositories for $10/month - more than ample for my needs), but their new plans start at between $7-$15/month and offer a lot of bang for the buck.

What makes them so great? Awesome service. I've been working on a dev project for VSSDK.com for a while now and had an SVN repository hosting source control for that project on a different server. This week I was able to get a .dump of that Repository (shout out to Kris Hering on the quick turn-around for that one), and then wanted to upload it to Hosted-Projects.com to move the entire repository over there.

Not only was Hosted-Projects.com able to import my entire Repo in literally a matter of minutes after my request, but they also completely re-purposed one of my existing repositories in order to meet my finicky requests in easing the transition.

In short, if you're using SVN and need hosting, you're stupid if you don't look into using Hosted-Projects.com. You can't beat them for the price (I've never had a problem with them being down or unavailable), and their service rocks.

April 25, 2007

The Visual Studio SDK

So, what's Mikeey doing to keep himself occupied of late? Well, other than the Longhorn Roadshow (which has been a hoot), I'm busily working on a bunch of stuff focused around Visual Studio Extensibility.

Keep tabs on my efforts here: www.vssdk.com.  

April 12, 2007

Circumventing the Server of Origin Policy

In security circles you're branded as pure evil if you talk about circumventing the Server of Origin Policy that helps protect JavaScript interaction from being hijacked by hax0rs. Frankly, that's with good reason - in the vast majority of cases.

But still, when I have something like blog.angrypets.com and want to be able to let it tie in to something like statusupdates.angrypets.com (via the XmlHttpRequest Object) it would sure be nice to just have my JS directly load/connect to statusupdates.angrypets.com. (As a case in point, blog.angrypets.com is hosted as a TypePad blog - so it's not like I can wire up a server-side proxy of an WS goodness that might be exposed on statusupdates.angrypets.com. Not to mention that just 'blindly' proffering proxies in that manner can also get you in to a HEAP of trouble when it comes to security.)

What we need is a SAFE way to trust external domains for direct linking. I think a killer way to do it would be to put a servers.trusted file right in the root of your site (i.e. on par with robots.txt and favicon.ico). This servers.trusted file would simply provide a list of trusted endpoints that could be deemed trusted by the site owner in terms of 'circumventing' the domain of origin policy. That way www.angrypets.com could be trusted to work with just plain ol' angrypets.com or scripts.angrypets.com, and so on. It could also be trusted to interact with other sites that I own, like common.overachiver.net, and so on. Likewise, if you trusted a service proffered by Google or MSN, you could 'link' there as well (if that floated your boat).

And as for any worries that hackers might somehow 'poison' your sites by overwriting this file: if they're able to modify a file at the root of your site then your last concern is the possibility of XSS via XHR injection.

Of course, to implement this 'change' would take a miracle - as all browser vendors out there would need to implement a standard way of permitting their JS runtimes to check for the existence of a .trusted file, parse it, and then 'trust' the specified endpoints.  So, it's sadly likely to never happen.

March 16, 2007

Ajax: Links Round-up

Over the past few months I've had the chance of creating two full-blown presentations for Microsoft Technet/MSDN dealing with AJAX. (Each 'presentation' was a for an hour long presentation with accompanying demos - I'll post links to them if I ever see them become available on the MS site.) The first presentation dealt with Ajax Security Best Practices in general (i.e. not just focused on Microsoft's AJAX offerings, but AJAX in general). The second presentation was a round-up of ASP.NET AJAX Best Practices.

In the process of creating those sessions, I ended up doing tons of online research, which resulted in hundreds of links. What follows is a filtered/aggregated list of some of the resources that I used - though this list is by no means exhaustive (and many of the links in the Intro section are pretty obvious - but the other links are all excellent).

Introduction

AJAX Defined
http://www.adaptivepath.com/publications/essays/archives/000385.php

The Benefits of AJAX
http://www.developer.com/java/other/article.php/3554271

http://dotnet.org.za/adam/archive/2005/04/12/17006.aspx

AJAX has been around for a while

http://www.axentric.com/posts/default/8

AJAX Architecture
http://www.adaptivepath.com/publications/essays/archives/000385.php
http://en.wikipedia.org/wiki/XMLHttpRequest

AJAX Still suffers from the same problems as other application development
http://dotnetslackers.com/Ajax/re-42465_Why_some_of_.....

Code Management and Extensibility

JavaScript best practices

http://www.bobbyvandersluis.com/articles/goodpractices.php

Unobtrusive Coding

http://ajaxpatterns.org/Why_Ajax_Patterns

http://ajaxpatterns.org/

http://softwareas.com/ajax-patterns

http://www.w3schools.com/tags/tag_font.asp

http://snook.ca/archives/javascript/clear_links_to_1/

http://www.asp.net/CSSAdapters/Default.aspx

http://ajax.asp.net/docs/

ASP.NET AJAX Behaviors and Extenders

http://ajax.asp.net/docs/tutorials/ExtenderControlTutorial1.aspx

http://ajax.asp.net/docs/tutorials/IScriptControlTutorial1.aspx

Benefits of Unobtrusive Coding

http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

http://digital-web.com/articles/separating_behavior_and_structure_2/

http://www.bobbyvandersluis.com/articles/goodpractices.php

http://snook.ca/archives/javascript/clear_links_to_1/

Accessibility

W3C Accessibility Guidelines

http://www.w3.org/TR/WAI-WEBCONTENT/

Accessibility in General

http://aspnetpodcast.com/CS11/blogs/asp.net_podcast/archive/2006/.....

http://www.thinkvitamin.com/features/design/whats-next-for-web-accessibility
http://developer.yahoo.com/yui/articles/gbs/gbs.html

http://blindconfidential.blogspot.com/2006/05/quagmire-of-web-accessibility.html

Accessibility and AJAX Applications

http://www.dashes.com/anil/2005/09/06/web_development

http://www.washington.edu/computing/accessible/accessibleweb/ajax_accessible.html

http://www.maxkiesler.com/index.php/weblog/comments
/how_to_make_your_ajax_applications_accessible/

Progressive Enhancement / HIJAX

http://en.wikipedia.org/wiki/Hijax

Scalability

AJAX and Scalability

http://west-wind.com/weblog/posts/2725.aspx
http://www.relevancellc.com/2006/4/21/ajax-and-server-scalability-theory-and-practice

UpdatePanels and Web Services
http://west-wind.com/weblog/posts/2725.aspx

http://blogs.msdn.com/mikeormond/archive/2007/01/31/the-asp-...

http://blogs.msdn.com/mikeormond/archive/2007/02/01/on-updatepanel-...
http://www.dotnetjunkies.com/Article/46630AE2-1C79-4D5F-827E-6C2857FF1D23.dcik
http://blogs.msdn.com/tess/archive/2006/02/23/537681.aspx

Micro Caching

http://aspalliance.com/251

http://msdn2.microsoft.com/en-us/library/system.web.caching.aspx

Security

General AJAX Security

http://www.securityfocus.com/infocus/1868

http://www.it-observer.com/articles/1062/ajax_security/

http://www.net-security.org/article.php?id=949&p=1

Security Best Practices

http://webdesign.about.com/gi/dynamic/offsite.htm?site=http://www.tec...

http://blogs.ittoolbox.com/security/dmorrill/archives/ajax-and-information-security-10026

http://msdn2.microsoft.com/en-us/library/aa302417.aspx

Validation Problems
http://www.net-security.org/article.php?id=949&p=4

ASP.NET and Web Attacks

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/....

Cross Site Scripting

http://en.wikipedia.org/wiki/XSS

http://www.cgisecurity.com/articles/xss-faq.shtml

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/PAGHT000004.asp

http://getahead.ltd.uk/dwr/ajax/cross-domain-xhr

XSS and CSRF

http://sla.ckers.org/forum/read.php?3,3843,3871#msg-3871

http://en.wikipedia.org/wiki/CSRF

http://sla.ckers.org/forum/list.php?4

http://ha.ckers.org/xss.html

Anti XSS Library from Microsoft

http://www.microsoft.com/downloads/details.aspx?FamilyID=...

Anti CSRF Measures – ViewStateUserKey
www.blackhat.com/presentations/bh-usa-06/BH-US-06-Gallagher.pdf

http://msdn2.microsoft.com/en-US/library/system.web.ui.page.viewstateuserkey.aspx

http://www.hanselman.com/blog/ViewStateUserKeyAndInvalid
ViewstateWhenPostingBackDuringFormsAuthentication.aspx

Defense in Depth and ASP.NET Authentication/Authorization
http://cyberforge.com/weblog/aniltj/archive/2004/10/09/685.aspx

JS and CSS ‘history sniffing’

http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html

XMLHttpRequest Best Practices

http://www.devx.com/webdev/Article/28861

http://jeremiahgrossman.blogspot.com/2006/07/my-black-hat-usa-2006-presentation.html

http://www.darknet.org.uk/2006/04/ajax-is-your-application-secure-enough/

http://getahead.ltd.uk/dwr/ajax/cross-domain-xhr

Xml Poisoning

http://msdn2.microsoft.com/en-gb/library/system.xml.xmlreader.
canresolveentity(VS.80).aspx

http://msdn2.microsoft.com/en-gb/library/system.xml.xmlresolver(VS.80).aspx

http://msdn2.microsoft.com/en-gb/library/system.xml.xmlsecureresolver(VS.80).aspx

http://forumsystems.com/papers/Anatomy_of_Attack_wp.pdf

Microsoft Patterns and Practices: Improving Web Application Security – Threats and Countermeasures

http://msdn2.microsoft.com/en-us/library/ms994921.aspx

http://www.microsoft.com/downloads/details.aspx?FamilyId=....


Additional AJAX Attack Vectors

http://www.net-security.org/article.php?id=949&p=1

March 14, 2007

Expression Web: Partner Portal Starter Kit

If you haven't taken time to play with the new Expression line of tools provided by Microsoft, you should give them a try. I've been a pretty big fan of Macromedia's Dreamweaver for a few years - even though it has increasingly become more and more of a resource hog. But Microsoft's Expression Web is actually a full-on, viable, contender - which is HUGE, considering that it's a 1.0 release. Sure, it's got a couple of warts (all V1 software does), but I hands-down prefer it over Dreamweaver. Better yet, if you're an ASP.NET wonk, grab a trial of Expression Web today - as it will be the designer for Visual Studio Orcas. (Well, it would probably be more accurate to say that "Orcas" and Expression Web will be sharing a designer based on the same underlying core - I'm sure "Orcas" will heap on the additions/improvements.)

At any rate, Expression Web provides some really killer CSS functionality, and gives you a boat-load of options for managing styles, formatting, and so on. It REALLY does make the notion of using a designer/tool completely feasible when it comes to WYSWYG CSS - which is a major feat. They've also added some cool innovations in terms of dragging/resizing padding and margins, and so on.

How do I know all this? Well, I spent about a month actively working with the tool to create a Starter Kit for Expression Web. You can check it out on the Expression site at Microsoft.com - it's the Partner Portal Starter Kit. The idea for this starter kit was to take a 'CSS Zen Garden' approach to styling one ASP.NET page in a variety of different ways - using ONLY CSS.

NOTE: If you want to download the starter kit, make sure that you grab the password for the zip files on the download page.

March 13, 2007

C# 3.0

If you are involved in .NET development and aren't subscribed to Scott Guthrie's blog, then make sure you zip over to his blog and read two of his latests posts on upcomming changes for C# (and VB.NET) in the "Orcas" timeframe:

Automatic Properties, Object Initializers, and Collection Initializers
Extension Methods

I got a sweet preview of these goodies at the ASPInsiders summit in December, but Scott does a great job of walking you through these new additions in a way that makes their strengths, motivations, and impact very easy to grok. The Extension Methods post, for example, will probably give you more of an overview of what LINQ is if you just follow-through it than any other resource out there - as it shows you exactly what LINQ 'comes from'. (That, and as you read about extension methods you'll see that it represents a killer new paradigm: All the benefits of 'rapid development' associated with dynamic languages/duck-typing (ala Ruby), but with strong-typing under the covers to ensure that your code is still very robust, and remains fast/scalable.)

March 12, 2007

ASP.NET AJAX and Url Rewriting - Redux

So, at the end of January, I posted about a clean/easy fix to getting ASP.NET AJAX and Url Rewriting working in tandem.

The approach was pretty simple: just create a new class that inherits from an ASP.NET Form control, and override its RenderAttributes method to 'inject' the location of the rewritten page. It only took a few lines of code, and (if using Master Pages) was pretty painless.

But Scott Guthrie came up with a better solution - using a Control Adapter. The benefits? Simple: you don't need to override any controls. Instead you just drop in a .browser file telling ASP.NET that you'd like to modify your output on the server for ASP.NET Form Controls on the way out, and you're basically done. That makes for a much cleaner option - and you don't need to worry about any problems in the designer that might arise from overridden controls.

Go check out his solution. He provides an excellent overview of how everything works, and even provides the sample code. He asked me to help him test it out to make sure it would meet my needs, and it literally took only 3 minutes to implement - so if you're doing any type of AJAX with  ASP.NET 2.0 and need to implement url rewriting with ASP.NET or even with an ISAPI filter, this is the route to go.

February 10, 2007

ASP.NET Master Pages and Robot Instructions

I just love Master Pages - they make my life so much easier.

But every once in a while I find a case where they can be a bit problematic. For example, I'm building a site and just created a page where I don't want search engines/bots to catalog or follow any of the links found in the page once it's rendered.

Instructing the bots is easy, just plunk:

<meta name="robots" content="noindex,nofollow" />

Into the header, and all is fine. But obviously I don't want to put that into my Master Page. I suppose I could figure out a way to put it in the Master Page and then only conditionally 'render' based on some variables that I configure for every page (or via non-default, etc.). There's also the issue of what kind of control/tag you could stuff into the Master Page's header - since ASP.NET 2.0 doesn't really allow you to put these kinds of controls into the header. (Something I touched upon previously...)

So, with that in mind, I chose the approach of just dynamically adding a new literal:

private void SetNoIndexNoFollow()
{
    Literal robot = new Literal();
    robot.Text = 
        "<meta name=\"robots\" content=\"noindex,nofollow\" />";

this.Page.Header.Controls.AddAt(4, robot);

}


Note that I'm not using Controls.Add(), but Controls.AddAt(). This lets me put the meta tag exactly where I want it.

January 31, 2007

ASP.NET AJAX and Url Rewriting

UPDATE: While the approach listed in this post is still a valid option, Scott Guthrie provide an even clean approach that make this even easier to implement. I've blogged about those improvements and provided a link to his post here.

First of all, thanks to fellow ASPInsider Scott Mitchell for his insanely thorough article on how to configure Url Rewriting with ASP.NET 1.1. What follows is an overview of the additional tweaks I needed to put in place to get Url Rewriting to work SEAMLESSLY with ASP.NET 2.0 and ASP.NET AJAX.

I'm currently involved in building a website that requires a LOT of url rewriting. Initially I didn't plan on having any post-backs, so I pretty much ignored the fact that Url Rewritten pages will post-back, by default, to the 'translated' url. So, if I rewrite:

http://mysite.com/name_of_product_here
to
/pages/products.aspx?id=name_of_product_here

any time a user issues a postback from that page, they'll be posting back to:
http://mysite.com/pages/products.apx?id=name_of_product_here

That's not a huge deal, I guess - unless you really want the urls on your site to be 'hackable' (i.e., you want to treat the urls on your site as a type of navigational interface that end-users can use if they want). Scott Mitchell's Url Rewriting article showed how to deal with that by creating a custom implementation of System.Web.UI.HtmlControls.HtmlForm. The gist was just to override how it rendered its attributes, and strip out the action attribute.

The nice thing too, is that with ASP.NET 2.0 Master Pages, I only had to 'swap out' the standard HtmlForm tags with the tags for my over-ridden/inherited HtmlForm class once. Even better, there was no need to compile my overridden class as I was able to just dump it in the App_Code folder. To reference code in the App_Code folder, you just need to remember that it will be compiled on your server, and output to "App_Code.dll"... which means you can register your own tags like so:

And, hooking that form into my master page was simple, I just had to replace the opening tag:

and closing tag:

Using Scott's method of overriding a form control that doesn't emit an action attribute completely solved my issue with Post-backs and url-rewriting in ASP.NET 2.0. But with ASP.NET AJAX installed and running on some of my rewritten pages (especially coupled with an UpdatePanel), having a blank/default action attribute just wasn't working.

Using Fiddler I could see that my AJAX requests were actually attempting to access: /pages/ - with nothing else specified (i.e. not /pages/products.aspx or anything - clearly something was messed up). Accordingly (since I had a default document set up in the specified location), I was getting ViewStateMac errors/warnings. In other words, my AJAX requests were getting warnings that were 500 errors. The net result though, was that my update panels/ASP.NET AJAX was broken.

Happily, my Url Rewrite Module made use of the following logic to store the 'original' (as in un-rewritten' url). Storing it in Context.Items is a light-weight way to ensure that it sticks through the entire request-response cycle:

Knowing that I had access to the 'pretty' url stored in Context.Items, I just made a minor tweak to the code that Scott provided in his article. The purpose of my tweak was to explicitly set the location of the action attribute - without having to add an 'Action' property or any other thing to my custom class. The entire class is listed below (with it's namespace):

using System;
using System.Web;
using System.Web.UI.HtmlControls;

namespace SSV.Rewrite
{
/// <summary>
/// Summary description for ActionlessForm
/// </summary>
public class RewriteForm : HtmlForm
{
protected override void RenderAttributes(
System.Web.UI.HtmlTextWriter writer)
{
writer.WriteAttribute("name", this.Name);
base.Attributes.Remove("name");

writer.WriteAttribute("method", this.Method);
base.Attributes.Remove("method");

this.Attributes.Render(writer);


string action = Context.Items["Original_Path"] as string;
if(action != null)
writer.WriteAttribute("action", action);

base.Attributes.Remove("action");

if (base.ID != null)
writer.WriteAttribute("id", base.ClientID);
}
}
}


Not much there, as you can see (the whole process was pretty painless). The beauty though is that my rewritten pages are now served up with a rewritten action attribute. So pages now totally post back to their rewritten location, and ASP.NET AJAX works perfectly with my Url Rewriting Scheme. So now I've got the best of everything: url-rewritting or tidying, hackable urls, and ASP.NET AJAX goodness.


Shiny.

January 23, 2007

Microsoft ASP.NET AJAX - 1.0!

It's finally here - as in just shipped today.

There are lots of existing AJAX frameworks out there, and MS has taken quite a while to finally deploy theirs as a 100% supported product, but I'm convinced it will gain tremendous market-share and become an almost de-facto AJAX framework for oodles and oodles of people.

On the note of why it took so long, something I've been a bit critical about in the past, I had the privilege of attending an ASPInsiders summit in December - and got some great insights into just how many hoops the ASP.NET team has to jump through to make something truly 'support ready'. For smaller shops, full support isn't that big of an issue - as long as devs have full access to the code, they're fine using whatever is available. For bigger companies (i.e. with lots of lawyers and pointy-haired bosses), they need someone to blame if things don't work out - so they typically won't touch 'external' code/components unless it comes with COMPLETE support. (Impatient jerks like me tend to forget things like that at times.)

And on the level of 'confessions', I do a lot of bashing of MS at times. Frankly, that's because some 'wings' of MS deserve it. I make my living with MS products, so I'm bound to be critical when they botch (in my estimation) something. But I've REALLY got to hand it to the ASP.NET team. They really try hard to make things work, and to meet real customer demand. A good case in point is that you can actually download core ASP.NET AJAX components as .zip files. That may seem like a trifle, but almost all source code that you can download from MS comes down bundled as a wretched .msi. MSI is a killer technology, and makes installation painless - I love it. But using it as a way to stuff a EULA in front of devs before they crack open sample code is just lame. Kudos to the ASP.NET team for breaking the mold and giving devs more power/freedom.

And kudos to the ASP.NET team for shipping. I know they've put in tons of cycles on making this framework work - and in making it cleanly extensible in the future.

UPDATE: ScottGu just blogged about the release, along with some of the great offerings involved (full source code, etc.).

November 30, 2006

Test XSS Post

Ignore this post - unless you get a JS popup. In which case your RSS aggregator does NOT have your back.

If you're reading this in a browser (i.e. visiting my blog) and get a popup, you've been pwn3d!!!! (jk)

Self-Replicating XSS Worm

So, I'm working (night and day, and day and night) on an 60 minute AJAX Security presentation that will be used by MSDN presenters to help remind web developers of ... you guessed it: AJAX Security.

But, I think I've been spending a bit too much time contemplating various XSS attack vectors. In fact, partially inspired by "Samy" I've come up with my own sinister plot, and thought I'd share it:

Disaster: 
3 Scoops Exploit, and 1 cup of negligence: Hacker manages to execute a persisted XSS attack against a site that blindly trusts either user-input, persists it, and outputs it to subsequent visitors. (i.e. like a forum site, etc.)

2 teaspoons of Malice: Hacker uploads/inserts an evil.js file into the browser, and after harvesting credentials (and possibly logging keystrokes, etc.) executes a snifty function called Replicate(). Replicate is a JS function that checks the referrer to the current site, if there is one, and then attempts various SILENT exploits against the referring page - attempting to locate other pages, formfields, etc that might be susceptible to persisted XSS attacks. (It can just use the XmlHttpRequest object to request, parse, and interact with referring pages (from the same site) because they won't be blocked from interaction due to the 'Server of Origin' policy.)

Mix Well, and Simmer: If other pages are compromised, the code injected in to them will instruct browsers to load the same 'evil.js' file, which will subsequently check new referrers and attempt to compromise them.

With any luck, huge chunks of an entire site could be swamped with credential harvesting, keystroke logging, self-replicating evil.... it's like the Borg all over again. (And, I'm sure evil (or good) genius hacker out there has already coded this pig... I'm just happy I was able to come up with this idea all on my own... )

November 10, 2006

Microsoft and HotFixes

I've lived for the past few years in total, abject, fear of hotfixes.

That's only because I've spent nearly an hour on the phone before waiting (after giving out a CC# - that wasn't charged) just to get one before.

But that was then.

Today I NEEDED a hotfix. MS needs to be slapped for not just giving you a number to call on their KB articles/links (seriously, go click the support link in that page...after 3 pages and trying to figure out who/what you are... you'll give up).

Since I couldn't find a good number to call, I just called MS' 1 800 number. The menu-ing system actually worked, and went something lik

... if you want support, press 2... .
... if you are a developer, press 3....
... if you would like a hotfix, press 1 (or 2.. can't remember)....

Then, like that I was connected. They just needed my first and last name, a phone number (in case we got cut off) and an email address. Then they needed the KB #. A brief warning about the nature of HotFixes (if you haven't pulled one down before), then they waited on the phone until the fix showed up in my email.

IMPRESSIVE. The whole thing took less than 7 minutes.

November 09, 2006

AspNetSql Providers and File Access Issues

BIG shout out to fellow ASPInsider Paul Glavich who saved my bacon on this one.

A while back I ran into an issue where membership info that I had saved to the ASPNETDB.mdf in my local site just didn't work after I moved the site to another location (i.e., to a different box). Turns out that since I had made some changes to provider details, and failed to explicitly specify an applicationName attribute, my Providers were all checking for logins/etc against a different appliation_id in the SQLEXPRESS database.

Scott Guthrie posted about it a while back.

So, imagine my surprise today when I ran into what seemed like the same thing: I moved my site, fired it up, tried to login, and bupkiss. Each time I'd log in, the page would just blink. Seemed to be EXACTLY the same behavior you'd get if your providers didn't explicitly specify an applicationName attribute. Only you can bet your sweet bippy I had explicitly specified that.

After yelling at my computer ("you lie!!!!1111oneoneone"), I posted an email. (Stepping in to the debugger I could see that the ApplicationName was indeed being handled correctly, but Membership.ValidateUser() was just never returning true. Worse, I could run copies of this site in VS 2005 and Cassini - I just couldn't run a copy of the site in a different IIS site listening for different headers.) Paul asked if both sites in IIS had the same perms. Well, duh... there it was. I had been so busy focusing on the ApplicationName goodness, that I had totally missed that.

The moral of the story? Actually, there are two:
1) Step away from the computer - rethink, it may not be what you think it is, etc.
2) The ASP.NET SQL Providers need to be SLAPPED for swallowing something HUGE like: "hey, dammit, I can't connect to the friggin' db because access to the 'attachable' SQLEXPRESS db is denied to NETWORK SERVICE."

October 03, 2006

Hosted-Projects.com - Excellent SVN Hosting

Subversion is the bomb. I started using it a little over two years ago, and I've really grown to love it. Especially with the use of TortoiseSVN - quite simply the most intuitive Source Control Client I've used.

For my own projects, I started hosting with www.svn-hosting.com about half a year ago, and I have been very pleased by:
1) Uptime
2) Server Responsiveness
3) Throughput
4) Customer Service
5) Price.

SVN-Hosting.com recently, apparently, changed their name to Hosted-Projects.com, but the transition (on my end) was so seamless that I didn't even realize that a change had been made until I nav-ed out to the site for this post.

If you're in need of Subversion Hosting, give these guys a try - they're very responsive, have great pricing plans, and their servers just work.

P.S. Sorry for the recent delay in posts folks - I was out sick all last week. The good news is that I'm feeling "much better now". (No, really, "I don't want to go on the cart!")

August 29, 2006

Fun with Enums

UPDATE: Sorry for the repost everyone - but when reading over my feed in my aggregator this morning I noticed some bad typos that anyone who CARED about this post would have a hard time with (i.e. some of my code samples had bloopers in them). (Note to self: Proof THEN publish...)

Yesterday I blogged about some upcoming changes to ReverseDOS. One of the changes involved letting users create <rule> entries based on 'verbs' describing the 'actions' of the current request being evaluated.

Using the [Flags] Enum worked out well here - as it provides me with the ability to specify multiple verbs, such that users can create 'combinations' of various activities that they would either like to prohibit or allow against a given directory. The enum is nothing special, and looks like so:

[Flags]
internal enum Verbs
{
    Head = 1,
    Get = 2,
    Post = 4,
    Query = 8,
    Refer = 16,
    Proxy = 32
}

The fun, however, began when I realized that I needed to give people the EASY option to create OR-ing combinations as well as AND combinations. For example: You want to block against a Proxy-ed request, and don't care if the request is HEAD-ed, GET-ed, or POST-ed. If you wanted to set that up, you'd technically need to create three rules:

<rules>
	<deny verbs="head,proxy">/pathHere/</deny>
	<deny verbs="get, proxy">/pathHere/</deny>
	<deny verbs="post,proxy">/pathHere/</deny>
</rules>

That, frankly, seemed quite ridiculous - who would want to have to do that - especially when the whole goal is to easily 'fight' spam.

So, I figured the following syntax (while spooky to a grandma) wouldn't be too PERL-ish to the average developer:

<rules>
	<deny verbs="head|get|post,proxy">/pathHere/</deny>
</rules>

As you can see, it's not perfect - but much simpler than the alternative. (And, it's technically a VERY lame example - cuz all you'd be worried about here is the Proxy action/verb - so bear with me and my lame examples).

In the end, however, I just wanted to let people easily specify OR-ing and AND-ing with a simple text attribute, and let ReverseDOS figure out (behind the scenes) what people meant. Which lead me on an amusing journey to the dark and evil land of recursion. (Actually, it was quite fun.)

In the end, my solution was REALLY over-built - as there just aren't enough combinations for the types of verbs logically available and associable, but the alternative to over-building was some lame type of hard-coding, so I decided to share my solution for anyone who's interested. Especially since this code should be pretty easy to 'steal' for any other operations involving enums and various AND-ing and OR-ing combinations expressed as text. 

For example, suppose we were dealing with PizzaToppings, expressed as a [Flags]-ed enum. With this logic if you specified: "TomatoSauce|PestoSauce, Cheese, Anchovies, Squid|Pepperoni", you'd be specifying that you REALLY wanted an adventure, not a pizza. The results for such a 'choice' of options would be:

TomatoSauce, Cheese, Anchovies, Squid OR
TomatoSauce, Cheese, Anchovies, Pepperoni OR
PestoSauce, Cheese, Anchovies, Squid OR
PestoSauce, Cheese, Anchovies, Pepperoni

The logic I used to calculate this (as an Array of Verbs[]) is as follows:

1) Pass in a string value indicating the serialzed 'choice' (where we break apart all of the 'AND-ed' options and size an output array of Verbs[], etc.) :

private Verbs[] LoadVerbs(string verbInfo)
{
    Verbs[] output;
    if (verbInfo.IndexOf("|") > 0)
    {
        string[] segments =
            verbInfo.Replace(" ", "").Split(new char[] { ',' });
        string[][] iterations = new string[segments.Length][];
        int bounds = 1;
        for (int i = 0; i < segments.Length; i++)
        {
            if (segments[i].IndexOf("|") > 0)
            {
                iterations[i] = segments[i].Split(new char[] { '|' });
                bounds *= iterations[i].Length;
            }
            else                 iterations[i] = new string[] { segments[i] };
        }

        output = new Verbs[bounds];
        int location = 0;
        output = this.RecurseVerbOptions(
            iterations,
            0,
            string.Empty,
            ref location,
            output);
    }
    else     {         output = new Verbs[1];
        output[0] =
            (Verbs)Enum.Parse(typeof(Verbs), verbInfo, true);
    }

    return output;
}

2) Use a bit of evil recursion to traverse down the 'list' of AND-ed options, and then as I do so, account for each OR-ed option as needed:

private Verbs[] RecurseVerbOptions(string[][] iterations, 
    int currentLevel, string currentOption,
    ref int outputLocation, Verbs[] results)
{
    string currentValue;
    string verbsOption;

    for (int i=0; i < iterations[currentLevel].GetUpperBound(0)+1;i++)
    {
        currentValue = iterations[currentLevel][i];
        if (currentOption.Length > 0)
            verbsOption = string.Format(
                "{0},{1}",
                currentOption,
                currentValue);
        else             verbsOption = currentValue; // start a new line...         if (currentLevel < iterations.GetUpperBound(0))
            this.RecurseVerbOptions(
                iterations,
                currentLevel + 1,
                verbsOption,
                ref outputLocation,
                results);
        else         {             results[outputLocation] =                 (Verbs)Enum.Parse(typeof(Verbs), verbsOption, true);
            outputLocation++; // increment for the next position         }     }     return results;
}

In the end, this works perfectly - but, as I said, it's a bit over-built. (Still, it was fun.)

June 26, 2006

WinFS is gone. Now what?

If you haven't heard the announcement already, you likely won't care about this post.

But MS has pulled the plug on WinFS - for now they claim. As a developer I guess I can understand the idea of wanting to 'overbuild' the crap out of something and make it just perfect. (Only I've never been allowed to do that anytime I was getting paid...) As a consumer I'm totally not happy about it though.

Lots of people have said a number of things about the decision to nuke WinFS. I could sound off for a while on my own thoughts.... but instead I'll link you to a set of excellent observations made by Paul Murphy.

Read his WHOLE post.
It will only take a second - and you'll find it well worth the time (I promise). I'll wait here.

Done?

I liked the following lines:

For the first time ever a company is releasing an operating system where the primary design goals benefit someone other than the computer's owner.

Vista, to be as blunt as possible, is not being built for consumers or businesses. It's being built so Microsoft and Verizon can make money selling you movies.

What Microsoft really means is Windows Vista is secure from the threats presented by the consumer to content owners and that it provides a platform for digital distribution.

So as early as a few days prior Microsoft was hyping WinFS with sessions and classes at TechEd. They were energizing a base of hard core developers about a technology they knew would never see the light of day. It’s this behavior that has pitted me against myself when it comes to Microsoft.
   

(If you didn't read his post - go read the whole thing , he makes some sobering points.)

I can't believe MS doesn't realize that they're hurting right now (i.e., I'm sure they know). Each missed date and pulled set of functionality at this point (not to mention the misdirection and lies Paul mentions) are pissing off their core base of geeks like me who are were enamoured of them. 

And remember, despite my complaining I still believe that Vista is a great new OS - with lots of new functionality and features. It's just that it's terribly SHY of the revolution promised by MS.
It has been seriously over-hyped and over-promised. Surely that wasn't intentional, but it doesn't change the fact that given what Vista COULD have been, it's fallen far short of the mark. In other words, I think that the biggest software project in the world, is starting to look  like a failure on some levels. And I'm not the only one saying that.

Hopefully when the Vista dust settles MS will hold the mother of all post-mortems, figure out what it needs (a drastic re-org), and get competative again. Otherwise I'm just going to start calling them Big Blue 2.0.

June 07, 2006

Hacking Remote Desktop Connections

Recently while trying to 'Remote Desktop' into a remote server on a VPN I got the dreaded "Terminal Server has exceeded the maximum number of allowed connections".

I contacted the Admin at the remote site, he poked around a bit in the Remote Desktops Management MMC - but couldn't see ANY connections.

Then I stumbled upon this great article from Scott Forsyth - showing spiffy command line options (available even in XP) that let you do some better interogation.

Querying with qwinsta /server:vpnIPAddyHere I was able to see two disconnected winstations/sessions, nuked them, and then got on.

Only, there was ONE little trick that I had to pull off. Since I was connecting via VPN, I wasn't a member of the remote domain - in fact, my login to the remote box was limited to only one machine (a SQL Server).  So qwinsta wouldn't work - as I didn't have permission to access it.

The solution? Simple: open up Windows Explorer to \\remoteMachineName\c$ (or some other share). In order to connect to a share you have to pass in credentials and get a Kerberos ticket. Once that's in place, it's good for roughly 10 hours in most cases... and once you have that ticket it then gets bundled with your subsequent requests with qwinsta and rwinsta. (Okay... so maybe that's not hacking... but it does solve the issue of qwinsta and rwinsta not letting you pass in optional credentials.)
 

Spiffy - and thanks to Scott for the excellent overview of those tools. Total life saver.

May 25, 2006

Missing ASP.NET Tab in Windows Server R2 and x64

Fellow ASPInsider Phil Winstanley recently blogged about an issue he had been monitoring in an email thread. Specifically, the email thread was strongly leaning towards implying that the ASP.NET tab wasn't supported in R2 and x64 editions of Windows 2003 Server (which would have been a BIG deal).

Well, the email thread he was monitoring was one that I started. (And was on a private forum where Insiders can post feedback to Microsoft and get help/feedback from other Insiders and MS folks).

BackStory:
Normally when the ASP.NET tab isn't in place, that just means the Server hasn't been instructed to map any of its sites to ASP.NET 2.0 in IIS. Mapping is easy - just jump to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 (assuming that the 2.0 Framework is installed) in a command prompt, and run aspnet_regiis with the -i and -enable switches (or with the -sn <path> and -enable switches if you just want to upgrade a single site).

Only, I had done that, and a couple of other combinations - including uninstalling, re-installing, and even installing/mapping to lower versions (i.e. aspnet_regiis is installs whatever version of the framework the .exe is located in... so v1.1.4322 will do ASP.NET 1.1) and I still wasn't getting the ASP.NET tab to show up. (i.e. I had tried a number of 'vulcan death grip' switch options - but nothing).

Paranoia sets in:
I started to worry that maybe the ASP.NET tab wasn't supported in R2, and therefore launched an email thread - hoping that I had just missed something stupid. Another Insider with much better search skills than me (since I _did_ google first), pasted a link from the MS Office site  that surely seemed to indicate that there was a basis for my paranoia. Amazingly, it stated:

The ASP.NET tab does not appear on x64-based editions of Windows Server 2003 and Windows Server 2003 R2. This tab also does not appear if only one version of ASP.NET is allowed in the web service extensions.
[ exasperations added (original) ]

Worse, it repeated that notification over and over again throughout the page. Huh? What??!!

The Truth about the ASP.NET tab in R2 / x64 Installations:
Luckily Scott Guthrie noticed that my panties were starting to get in a wad (they do that some times), and put me in touch with some folks at MS to help look in to the situation. We weren't able to figure out what was up with my ASP.NET tab, but I did get some confirmation from MS:

The documentation on that Office page is false. In other words:

The ASP.NET tab is fully supported in all version of Windows Server 2003 R2, and is EVEN supported in x64/ia64 versions of Windows Server 2003 and Windows Server 2003 R2. The ONLY place that you won't see the ASP.NET tab is when you are running an x64/ia64 System and have IIS set to run in 32bit compatibility mode.

At this point I'm still NOT sure what caused my ASP.NET tab to disappear in my installation - likely just my incredibly good luck. That said, one of the caveats about getting the ASP.NET tab to show up is that IF you install IIS _AFTER_ you install the 2.0 framework, you have to run aspnet_regiis. (This wasn't my issue, I installed in the 'correct' order - and either way, running aspnet_regiis should make your ASP.NET tab display.)  So if anyone reading this is looking for their own ASP.NET tab - just run aspnet_regiis.

Conclusion:
Just for the heck of it though, I tried getting the ASP.NET tab in an R2 image, so I pulled up a Virtual Machine I was using for an upcoming demo and reverted it back to the 'base' image snapshot, then used the Add Remove Programs | Windows Components dialog to 1) add IIS, 2) Install the .NET Framework (it's an optional component on R2 versions of Windows Server 2003).

Aspnet_r2

And, Wohoo! Everything worked -with the exact same IIS/ASP.NET options that I had chosen before. Still no idea what happened -  but some day I'll just repave (after I head to Costco and get a three-pack of chickens to sacrifice along the way, just to make sure).


May 24, 2006

Really Simple Syndication

So, forget what you already know about RSS - that it's for blogs, etc. (Because while it's true that blogging and RSS are almost synonymous these days, RSS doesn't have the word "blog" or "podcast" or any other word typically associated with blogging in it.)

But, as you know, RSS stands for Really Simple Syndication.

In computing you've effectively got two major mindsets for communication (lately): the request-response model (which is really what the web is based on), where users request information when they need (think of a trip to google); and the newer trend towards publication and subscription (or pub-sub). PubSub attempts to give clients/users the ability to 'sign up' to resources they express an interest in, and be updated when new content is delivered.

RSS just happens to be a great way to describe 'published' or syndicated material. But it isn't limited strictly to rants about the government, reminiscences of vacations, recipes, technical blather, or anything else typically associated with blogging.

Enter RSSBus.

I'm still not quite sure what to make of it, but it looks like an RSS-instead-of-UDDI approach to systems integration. I still have a bit of a hard time shaking my pre-conceived notions about RSS (and its relation to blogging/etc.), otherwise, I think there might be some merit in some enterprises. (Though I tend to wonder if it would go over as a HUGE success with pointy-haired bosses ("huh? what? Web services using blogging technology? Wow... yeah, that sounds cutting edge - does it provide support for lego-mind-storms via XML?"), and be sneered at by developers out of a pure sense of NIH (Not Invented Here)?)

May 23, 2006

CodePlex: Grasshopper sees the wisdom

CodePlex.

My immediate thought was that if this thing is supposed to be a replacement, effectively, for gotdotnet.com, then it was going to be a dissapointement - because not everyone is going to be able to poney up the $10k for a shiny VSTS Level/Caliber MSDN Subscription.

But it looks like there are ways... 'around' that. Only, I don't think the intention is to get you around that obstacle. I think the intention is to get you to ENJOY that obstacle - so much so that you become tempted by it (and think about setting up a tent, or maybe a lemonade stand, complete with check-in constraints, and all the other goodies).

Frankly, not bad.

I think the site could use some definite filtering/navigational help - but it's insanely young. Otherwise, I'm going to keep my eye on it. I may even end up dropping ReverseDOS on it once I make a few more major mods.

May 03, 2006

Xml in the Shadow of Hanselman

Confession: I really enjoy writing my Xml4Fun articles, over on MSDN. Sure, sometimes I manage to get myself in a bit too deep (in terms of scope), and some articles take way too long to actually complete - but it's an excellent challenge, and something that I really enjoy.

Worry: Only, I don't know everything about Xml. Sure, I know waaaaay more than say... my Grandma, or even my .... brother (who isn't in development/IT).  Heck, I even know more about Xml than most developers that I _personally_ know. And hey, I've got a number of great books on Xml... so I can solve most problems when I need to. Right?

Only... there's this nagging feeling that some day I'll do something obscenely stupid. In one of my articles.

And it will be spotted by somebody who really knows what they're doing, like Scott Hanselman - who also has a Coding4Fun column; so it's only a matter of time 'till he checks out one of my ideas and then exclaims: "What was this guy thinking??!!!". 

So yeah, I seriously dig Xml (hey, it's data) - but some day my cover will be blown, and I'll be found out. And I'll cry like a baby. In front of people.

May 02, 2006

ComXT 1.3 Available

Ken Arway has been up to more good with his ComXT efforts. He's added XML Diff functionality (very cool) and the ability to spam test data into a sample doc generated by a supplies XSD. (This is in adddition to the XPath, XSLT, and schema inference functionality already in place.)

Comxt_1

Stated differently, ComXT is shaping up very nicely. I've already got it deployed in my toolbox, and find it useful in a number of situations. Go get yours today.

(For those of you joining the party a bit late, part of the idea for ComXT came from my Xml4Fun article on 'rolling your own XSLT engine' a while back - but at this point Ken has completely taken the ball and run with it - providing oodles of additional goodies.)

April 26, 2006

101 Samples for Visual Studio 2005

About 1 year ago when I first started working with 3 Leaf we were _busy_ working on various aspects of prepping 101 sample applications designed to show off the cool new stuff in VS 2005/ .NET 2.0. I was too late to author any of these demos/sample applications (*sniff*), but I proofed/modified many of them, and I've toyed with some of them over the past year as they've slowly been modified to account for all of the subtle changes between various beta builds and the final RTM of VS 2005. (i.e. I know some of these samples intimately...too intimately.)

The funny thing though is that I never realized where they ended up. Which sucked cuz there've been a few times where I would have liked to link people to them in order to see a new technology in .NET 2.0 (or SQL Server 2005) modelled in a simple-to-grok fashion.

Happily I now can as I see from reading Dan's blog that they've been released for consumption!!!

Go check them out, they're some awesome resources that you're sure to love. (My favorites are the Data Access (which I spent the bulk of my time with) and Base Class libraries samples...)

April 13, 2006

Visual Studio Extensibility: Guided Tour

Yeaaay.

One of the cool things about Evangelism is seeing some of your past efforts go into things like MSDN for use by the rest of the world.

A big project that I did for 3 Leaf a few months ago has finally made it to MSDN. The whole project focused on providing a tangible way for developers to get their feet wet and get a decent grip on how to Extend Visual Studio 2005 and Visual Studio 2005 Team System. It was a fun project (though LONELY at times digging through reams of docs...), and it's finally now ready for consumption on MSDN.

Link: Extensibility Guided Tour

Vsip

(Note, you'll likely want to browse that in IE if you want the navigation to work - whatever nav tree thingy they're using on MSDN just doesn't work with FF.)

As you can see from the Screen Cap of the nav-tree above, there's quite a bit of content there. None of it is too in depth, just a few steps above and beyond a really global 'hello world' approach that helps introduce Extensibility, discusses some of the underlying concepts and benefits, and provides work-able samples to help devs get their feet wet. It includes info on three different ways to extend VS 2005 (Macros, Add-ins, and VSPackages) and also covers some rudiments of VSTS extensibility... along with a couple of pointers on how to deploy changes and the likes.

April 10, 2006

SQL Server Everywhere Edition

Hmmm.

http://www.microsoft.com/sql/letter.mspx

Funny that. I recently worked on a PPC app, and noticed that VS 2005 had full-blown support for SQLMobile Databases. I remembered thinking that it would be _kinda_ cool to fiddle with that mobile engine to see if there wasn't some cool way to expose it for desktop apps.

Looks like that's exactly where MS is going with it.

Access, thy days are numbered.

Here's a well-done FAQ that helps answer some questions about SQL Everywhere.

It will be interesting to see how this pans out... (overall, I'm thinking that this looks like a really level-headed release that will provide lots of good use for non-enterprisey type applications.)

April 07, 2006

Sproc Unit Testing in SQL Server

How to implement unit-testing for sproc changes in SQL Server - a re-heated RepeatableRead. [Read more...]

March 16, 2006

How to Kick your own A$$ in 5 easy steps

Step 1: Build a Virtual Machine.
Step 2: Install .NET 2.0 Framework and SQL Server Express on your new VM.
Step 3: Change the Name of your VM (i.e. Start | My Computer | Properties ... then change the name and reboot).
Step 4: Curse and wail because there's OBVIOUSLY something wrong with your VM/Network/Router that won't let see it from you host PC/Laptop.
Step 5: Change Network Library configurations and modify surface area settings... to no avail.
Step 6: (So, I lied, big deal; 6 steps not 5) On the VM, run SQLCMD.exe and realize that you still can't log in to the local machine.

At least, that's what I think happened. (It doesn't help that my installation of VMware Workstation is totally screwed up today though - it's the goofiest thing: I can ping, and nslookup fine. I can even use TCPView (from SysInternals) and see my VMs full-blown opening connections to remote endpoints, but I simply can not get ANY of my VMs to return a single damned web page - in either FF or IE. (None of the endpoints ever respond, apparently - leading me to think either VMware, or my router, is eating packets greater than some certain size.... ))

Honestly, today has been way too rough on me though...

At any rate (for those of you still around), it would appear that if you're trying to connect to a SQL Express Instance that's had it's name changed out from under it, you don't get far in life. Either that, or the Gremlins are crawling out of the TCP/IP stack and into all of my SQL Server client libraries. (Little <bleep>s.)

Moral of the story: 1) Maybe a better strat would be to Rename the box THEN install SSE? 2) Maybe I just need a VM exorcists?  3) It's definitely past my bed time.

March 08, 2006

ComXT - Free XML Tool Goodness

Those of you that may have read one of my recent Xml4Fun articles will remember the XSLTFormer tool that I created in that article as a light-weight, free, XSL Transform engine. Overall, I was pretty happy with the tool, but it did need some extra love (which I had intended to maybe give it some day in the future).

Ken Arway couldn't wait, and added his own love. Lots of it. In fact, he created a spiffy tool that provides lots of key, useful, xml goodness - all in one convinient wrapper. It slices, it dices, and it cooks low-fat hamburgers that taste great. Well, actually here's a feature breakdown that hasn't been run through the marketing department:

  • Xml Document Formatting
  • Xml Statistics
  • XPath / Namespace Lookups
  • XSL Transforms (my basic engine, but improved with 1) optional HTML output (as a tab - saweet) and, 2) elapsed time (helpful when you're comparing perf on multiple transforms)).

Go grab your copy today, it's free (including source) and it's available on GotDotNet's workspaces.

February 22, 2006

Coding4Fun: XSL Transform Tool

My latest Xml4Fun article is up on the Coding4Fun site at MSDN. (I didn't even know it was up until I got email about applying the tab-formatting to Rich TextBoxes..)

Anywho... I'll probably be extending the functionality on that little piglet here in a while (to do block tabbing - i.e. grab an entire block of text and tab or shift-tab it to align it). If I do, I'll post the source and binaries on my site.

February 02, 2006

Design Kudos

I, um, love eye-candy. I'm a sucker for a well designed UI.

To that end, Visual Studio 2005 is an overwhelming success. It's not just a great UI, it's a spectacular UI. I just love it, and find myself loving it each time I open it. Seriously, it's very well designed - not so 'candied' that it's distracting, but everything has a nice, soothing, polished feel to it. The entire IDE has a really clean feel to it thanks to the excellent UI work - and clean is a hard thing to pull off. I'm impressed.

I, um, complain a lot ... *more mumbling* - so ... I thought that some kudos might be in order here - cuz they're definitely deserved.

January 20, 2006

EntLib 2.0 - Does anyone use them?

So, EntLib 2.0 is available for download. It boasts jiggy-ness with the 2.0 Framework.

Back in the day, when EntLib was just a collection of Application Blocks, it pwned. I used the DAAB quite a bit - and loved it. The thing was almost perfect.

Then Application Blocks somehow became Enterprise Libraries. Only, it wasn't a marketing ploy - the libararies actually went full-blown mediaeval. And the Data Access stuff just got absurdly loopy/stupid - with all sorts of support for agnostic RDBMS accesss. In my mind, it was just too bulky to really be worth it.

And what was with all the configuration crap? I didn't give it much attention - I just remember installing EntLib seeing all sorts of crap about configuring this, that, and the other thing, and then looked at what they'd done to pooch the object model of the data access goodies and left the entire ball of wax for a future date. Only, that future date never arrived.

Strange thing is, I've talked with a number of people who've had about the same experience.

So, given that Enterprises will typically re-invent the wheel themselves (i.e. write their own libraries out of fear of 'Not Invented Here' causing them issues), does anyone really use EntLib? Am I just being a baby? Is it a pain in the butt, or is it pretty easy?

Would a bunch of simple to use assemblies be an even better approach than trying to pimp these libraries out for 'Enterprises'?

December 28, 2005

Software Curiosity: Foxit vs Acrobat

I've been running Adobe Acrobat 5 for the longest time now. I'm not even sure what the latest version of their free 'reader' is - I couldn't care less.

Don't get me wrong - I love the idea of a ubiquitous document format, and there's no argument - .pdf is it. It's just that I hate how crappy the reader is. 5 is way more stable than version 6 (when I tested it years(?) ago) - but it's still a miserable piece of software that takes entirely too long to load, consumes resources like a cannibal in a kindergarten, and crashes or locks-up entirely too often.

Recently I've been playing around with some spiffy .pdfs for a *cough*