Henry's profileUtterances on Software E...PhotosBlogLists Tools Help
    March 12

    Opening the Reports web application fails with "The request failed with HTTP status 400: Bad Request."

    Problem:

    You installed SQL Server 2005 Reporting Services (SP1, SP2, doesn't matter) with the optional Report Manager web application and opening "http://servername/Reports/Pages/Folder.aspx" with the browser results in "The request failed with HTTP status 400: Bad Request."

    Browser shows error message "The request failed with HTTP status 400: Bad Request." for http://servername/Reports/Folder.aspx

    Don't loose hope!

    If you're local, right-click and view the source code of the page. There's a StackTrace META element.

    If you're remote, go and check the LogFiles directory in "MSSQL.2\Reporting Services" or "MSSQL.3\Reporting Services" (or similar) in the SQL Server installation directory. Check the most recent ReportServerWebApp__datetime.log file. The stack trace should be at the end of that file.

    The stack trace probably reads like this:

    System.Net.WebException: The request failed with HTTP status 400: Bad Request.
    at Microsoft.SqlServer.ReportingServices2005.RSConnection.GetSecureMethods()
    at Microsoft.ReportingServices.UI.Global.RSWebServiceWrapper.GetSecureMethods()
    at Microsoft.SqlServer.ReportingServices2005.RSConnection.IsSecureMethod(String methodname)
    at Microsoft.SqlServer.ReportingServices2005.RSConnection.ValidateConnection()
    at Microsoft.ReportingServices.UI.ReportingPage.EnsureHttpsLevel(HttpsLevel level)
    at Microsoft.ReportingServices.UI.ReportingPage.ReportingPage_Init(Object sender, EventArgs args)

    Now go and check your %systemroot%\system32\LogFiles\HTTPERR\httperr1.log (or similar) file. At the end, there will be something like

    2007-03-12 15:49:30 127.0.0.1 3628 127.0.0.1 80 HTTP/1.1 POST /ReportServer/ReportService2005.asmx 400 - Hostname -

    This tells you that IIS rejected 127.0.0.1 as hostname. Which means your server is multi-homed and you haven't associated IIS's Default Web Site with 127.0.0.1 (localhost). This could help.  So does using "(All interfaces)". But, I don't know. I haven't tried messing with the Default Web Site on my server. (I fear IT would come after me and do bad things to me if I did.)

    Note: Reporting Service might be configured to use a different web site than Default Web Site.

    Solution:

    I suggest to change the Report Manager web site application configuration RSWebApplication.config in your "Reporting Services\ReportManager" directory.

    Make a backup copy first. Then set the value of the ReportServerUrl element to http://servername/ReportServer and delete the value in the ReportServerVirtualDirectory element. (These elements are mutually exclusive. If Reports fails to start with a yellow screen of death complaining that ReportServerUrl is not a configuration setting, delete on of them element values, willya?)

    <Configuration>
      <UI>
        <ReportServerUrl>
    http://servername/ReportServer</ReportServerUrl>
        <ReportServerVirtualDirectory></ReportServerVirtualDirectory>
        <ReportBuilderTrustLevel>FullTrust</ReportBuilderTrustLevel>
      </UI>

    Then start and stop the "ReportServer" application pool (or whatever the application pool is for your Report web). (Don't restart IIS unless you're in your scheduled downtime window.)

    Now the sun should shine and the world should be a better place.

    Recommended reading:

    Mike's Blog - Multiple Reporting Services instances on one machine

    RSWebApplication Configuration File Documentation

    March 11

    Adventures in ASP.NET 2.0: Bulk edit is not a low-hanging fruit

    For a project I'm working on in my spare time, I'm trying to get my head around ASP.NET 2.0 and, of course, AJAX.

    Not too long ago I thought I had reasonable understanding of the ASP.NET page processing flow and data binding. Now that I'm putting this belief to the test, it goes to show nothing's as easy as it seems.

    Usually, Microsoft is quite good at providing abstractions that make simple things easy and hard things possible. However, I came to learn that, especially for the latter part, ASP.NET 2.0 data-bound controls seem to have failed in providing useful and intuitive abstractions.

    It's so that I can't seem to be able to drag-and-drop together a simple master-detail editing page for a single master record and an open number of detail records. None of the 2.0 controls is helping, short of what I would have to do using a Repeater.

    I want to insert and edit, but maintaining all Insert, Read-only and Edit templates is cumbersome, and almost impossible with increasingly complex templates. Why, oh, why is there no simple way to build data-bound "Web User Template" controls?

    And I want bulk-edits (think Excel). The notion (and UI experience) of single-row edits drives me crazy. While I have been looking left and right for some simple solution, it's not until today that I found some relief in Matt Dotson's Real World GridView.

    But it is a GridView, and I would rather go with a DataList or even simpler control with the capability to disable some controls for one or the other data row. So I have to go and apply Matt's approach to a subclass of DataList or even Repeater.

    To reduce clutter, especially when there's a couple of drop-downs for each row of data, AJAX is an obvious solution and there's a lot of stuff in the AJAX toolkit that makes my life easier in other places as well. For instance, using AJAX makes the Back-and-Forward-Experience much cleaner. However, using AJAX in (and across) templated data-bound controls is far from obvious or simple. How do you debug something that doesn't render, i.e. code that doesn't run?

    So, to me, it seems I'm looking for (or applying) the wrong abstractions. Or, Microsoft's data-bound controls are, although complicated with all that templating, only means for collecting low-hanging fruits and so are the AJAX controls.

    A friend, who's working with me on the project, burdened with using CSS and themes to fix the UI mess I create, has a rich experience using PHP. Other than for Master pages ("Ahh, Server-Side-Includes!"), he's giving me a hard time when I try to convey the whole ASP.NET 2.0 "little or no page code" concept. Especially, when I need two weeks to find out how to assemble all-fancy controls to generate 50 lines of ugly-as-hell XHTML.

    Well, at least my failures are declarative.

    March 07

    Please don't call GC.Collect()

    The thing with quasi-religious beliefs is that they tend to repeatedly come up throughout the circle of life.

    Just recently, I reviewed a  friend's code where he implemented the Dispose Pattern horribly wrong, involving a call to GC.Collect().

    And today, a coworker on an internal distribution list refers to Rico Mariani's "When to call GC.Collect()" post from 2004, and, in particular, at the comments to that post, indicating there could be something complicated or unresolved in this matter.

    To me, it's quite simple.

    To avoid manifestation of superstitious rituals, let me quote Rico's main rules (emphasis mine):

    Rule #1

    Don't.

    This is really the most important rule.  It's fair to say that most usages of GC.Collect() are a bad idea and I went into that in some detail in the original posting so I won't repeat all that here.  So let's move on to...

    Rule #2

    Consider calling GC.Collect() [only] if some non-recurring event has just happened and this event is highly likely to have caused a lot of old objects to die.

    In addition, let me also quote from the memory usage post Rico refers to in the first paragraph:

    Almost-rule #1: Never call GC.Collect()

    If you think you need to force a collection something has gone very wrong. You have to ask yourself, what sort of collection do I think I need? Gen0, Gen1, Gen2? How do I know that the GC will decide to do the collection that I think I need? What did I do so that now I need that kind of collection?

    And, while we're at it:

    Almost-rule #2: Never have finalizers
    (except on leaf objects which hold a single unmanaged resource and nothing else)

    Checking in code using GC.Collect() should be allowed only after providing strong evidence and after several rounds of code review.

    Calling GC.Collect() is no workaround for anything, even less a fix. And when you start using GC.WaitForPendingFinalizers() you need code review and counseling. Seriously.

    And never, never, never call GC.Collect in the Dispose method. Never. This is like trying to empty a waste bin with a stick of Dynamite.

    Please, don't call GC.Collect(). Help Make Software Better.™

    Just my 2¢ after reading the garbage collection post and the comments, especially contrasting those from Darren Oakey and Ian Griffiths.

    March 05

    O Vista, where art thou?

    Chris Pirillo already said what I was thinking but was afraid to say (via Mini-Microsoft).

    Yet, my final point is different in that I really think Windows Vista is a great iteration of Microsoft Windows.

    However, it somehow goes to show the state of today's software. Apparently, developers are not able to adapt to a new operating system and environment that reveals almost each and every problem they create.

    They don't play well with installation and security, user interface guidelines, parallel programming and multi-processing.

    And it all shows on Vista.

    That frequent CTP are no means to speed up software migration. Everybody is just installing and passively "playing around".

    That a new Windows version just causes anybody to abandon old hardware projects. Or did you find a usable driver for your graphic card on Windows Update?

    That everybody waits for the very last second to get some piece of software out of the door. Or did an update for your legacy software ship in November 2006, when Vista was released? And now, isn't that "new" version still in Beta?

    That driver signing and application verification has become a necessity but customers still are not used to returning mediocre software to the store or vendor. Or did you ever return your copy of crappy DVD-authoring software?

    DEVELOPERS: YOU TOO PROBABLY DIDN'T TEST YOUR SOFTWARE ON WINDOWS VISTA YET!

    So, my advice for using Windows Vista is this: Get Vista pre-installed on a new, Vista-certified PC from a well-known and established PC vendor including each and every piece of hardware and software you think you'll need. Don't add some hardware unless there is an approved and signed driver available on Windows Update. Don't add software that is not Vista-certified.

    Return what does not satisfy your expectations. If the DVD-authoring software sucks, return the entire PC. Otherwise, you'll never get back the hours of your life hassling with that crap.

    I bought a custom-assembled PC from state-of-the-art components, thinking using it with Vista would be seamless.

    I'm back to reality.