Wednesday, January 07, 2009

I struggled today with inserting line feeds into a transformed XSLT document. Here is how I finally did it.

First, the <xsl:text></xsl:text> tag processes whitespace and can be used directly, for example:

<xsl:value-of select="./whatever" /><xsl:text>
</xsl:text>

The above will produce a linefeed.

However, I found that this made my code difficult to read. Instead, I declared a variable and set it equal to the text string:

<xsl:variable name="linefeed">
<xsl:text>
</xsl:text>
</xsl:variable>

and the used the value-of the variable on a single line to produce the line feed:

<xsl:value-of select="./whatever" /><xsl:value-of select="$linefeed" />

I think much more readable.

Any other suggestions would be greatly appreciated.

posted on 1/7/2009 1:16:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]
  • Blog reactions
  •  Thursday, December 18, 2008

    Received this error after an automatic windows update and reboot while I was working on a project in VS 2008.

    The components required to enumerate web references are not installed on this computer. Please re-install Visual Studio

    After the box rebooted, I couldn't connect to the web service for my project and couldn't refresh the references to my web service from within Visual Studio.

    I tried running

    c:\> devenv /resetsettings

    but nothing. My environment reset, but same - or at least similar problems.

    I looked through some of the other settings and found this:

    c:\> devenv /resetskippkgs

    Worked like a charm, but did have to update my web references, rebuild, etc... But it looks like I am back on track.

    H

    posted on 12/18/2008 4:02:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
  • Blog reactions
  •  Wednesday, December 17, 2008

    It seems that it is not possible to run the 64-bit version of the 2.0 extensions along side the 1.1 extensions for web applications. However, it is possible to run both in WOW64. There is a slight performance hit due to the additional layer provided by WOW64, but I haven't noticed it in my environment and only speculate that it might show up under extreme load.

    Here is how to switch (from http://support.microsoft.com/kb/894435) between versions.

    ASP.NET 1.1, 32-bit version
    To run the 32-bit version of ASP.NET 1.1, follow these steps:
    1. Click Start, click Run, type cmd, and then click OK.
    2. Type the following command to enable the 32-bit mode:

      cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1

    3. Type the following command to install the version of ASP.NET 1.1 and to install the script maps at the IIS root and under:

      %SYSTEMROOT%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exe -i

    4. Make sure that the status of ASP.NET version 1.1.4322 is set to Allowed in the Web service extension list in Internet Information Services Manager.
    ASP.NET 2.0, 32-bit version
    To run the 32-bit version of ASP.NET 2.0, follow these steps:
    1. Click Start, click Run, type cmd, and then click OK.
    2. Type the following command to enable the 32-bit mode:

      cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1

    3. Type the following command to install the version of ASP.NET 2.0 (32-bit) and to install the script maps at the IIS root and under:

      %SYSTEMROOT%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -i

    4. Make sure that the status of ASP.NET version 2.0.50727 (32-bit) is set to Allowed in the Web service extension list in Internet Information Services Manager.
    ASP.NET 2.0, 64-bit version
    To run the 64-bit version of ASP.NET 2.0, follow these steps:
    1. Click Start, click Run, type cmd, and then click OK.
    2. Type the following command to disable the 32-bit mode:

      cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 0

    3. Type the following command to install the version of ASP.NET 2.0 and to install the script maps at the IIS root and under:

      %SYSTEMROOT%\Microsoft.NET\Framework64\v2.0.50727\aspnet_regiis.exe -i

    4. Make sure that the status of ASP.NET version 2.0.50727 is set to Allowed in the Web service extension list in Internet Information Services Manager.
    Note The build version of ASP.NET 2.0 may differ depending on what the currently released build version is. These steps are for build version 2.0.50727.

    (It is important to note the need to re-enable the extensions in the Web service extension list in IIS, after running the aspnet_regiis.exe commands. They are disabled after each install and will produce a "Service Unavailable" error on the application if not.)

    Another issue that you will run into when installing the 1.1 extensions on 2K3 64-bit is the loss of the ASP.NET tab in IIS. While not a terrible problem, as you can switch the framework version for a web application from the command line, using the following command:

    aspnet_regiis.exe –s /w3svc/<identifier>/root

    Resources:

    http://support.microsoft.com/kb/894435

    http://support.microsoft.com/default.aspx?scid=kb;en-us;894435

    http://office.microsoft.com/en-us/winsharepointadmin/HA100598511033.aspx

    posted on 12/17/2008 10:54:03 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
  • Blog reactions
  •  Friday, December 12, 2008

    Umbraco.

    I've been working with it for almost a year now and tonight I managed to have an Ah-ha moment like none I have ever experienced.

    While working on a project for a client, I decided to look at building extensions methods in XSLT. After a few hours, I realized it's potential and also realized that I could move towards Umbraco as an environment, instead of Umbraco as a platform.

    Just a few rules that I want to share with you regarding XSLT extensions in Umbraco.

    1) Accept a string as input - you are working with XSLT, so it's really all strings anyway, so when you pass something into your extension method, be sure to pass it as a string, TryParse it and send something back that makes sense if it doesn't work.

    2) Return either a string or an System.Xml.XPath.XPathNodeIterator - If you are displaying the data directly, string, if you are iterating, comparing or anything else, XPathNodeIterator. This is what brought me to that conclusion.

    3) Don't "Skip testing (ignore errors)" in Umbraco. If it coughs, chances are you have a problem. Dig through the forums, post a little and wait. You'll get the answer eventually.

    4) Think atomically - every function call is self contained. Static methods/classes.

    I can't think of anything that I couldn't accomplish using XSLT Extensions and existing Umbraco functionality now. I had been writing custom asp.net user controls to accomplish everything I needed up to this point, but now realize that those user controls are better suited for moving an existing application to Umbraco, not necessarily for new development. I can accomplish just about everything I need using a combination of XSLT extensions, /BASE and some jquery (or other flavor of javascript framework).

    Here is a great example of accomplishing something meaningful with XSLT extension methods and here is something even better.

    Thanks Umbraco.

    H

    posted on 12/12/2008 4:29:18 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]
  • Blog reactions
  •  Wednesday, October 01, 2008

    Now that the media (and the DC drama queens) are shying away from calling the $700 billion dollar gift to Wall Street a buyout - actually reporting that there is the potential for taxpayers to actually make money from the deal, I am trying to make sure that I have my head wrapped sufficiently around what they are trying to accomplish.

    The treasury (via the FDIC) is going to purchase all "toxic" loans from troubled banks so that they can clear up their balance sheet and begin to meet the Federal regulations in order to begin loaning money again. They will be purchasing these failing (or failed loans at the full value (not really the market value, but the full value of the mortgage, even if the property values have dropped substantially) of the note - essentially taking ownership of the property and they owner will begin paying (or not paying) the treasury. This will allow the credit markets to being to outflow again to speculate against potential future inflows into a company that before had crumbling books, but now has a clean slate.

    The federal government then owns the notes that are not currently being paid on, hoping that those people who can't pay their loans will begin to do so as the market recovers.

    This is in hopes to stimulate the economy, especially in the area of housing starts, so that we can add more homes to an already flooded market whose values are propped up by the fact that loans were so easy to come by in the first place.

    Those worthless properties that the federal government (taxpayers) may or may not be paid on and any hope to foreclose the property are worthless because of the housing glut and the fact that the properties are virtually un-sellable. The hope is that eventually the market will recover and both the new housing starts and the foreclosed properties will regain value and eventually surpass their current values (from nothing) giving the taxpayers much needed relief and seeing a return on the 700 billion initial "investment".

    Remember, people ultimately foreclose when they can't afford their mortgage and they can't sell their property at or above the loan value. The houses they own are worth far less than the loan amounts that they have outstanding. The government can't do any better getting this money back and who in the world is going to start new houses, when the ones that we already have (most new, 5-10 years old) aren't moving and are depreciating - rapidly.

    Add to that the fact that we all of a sudden have $700 billion more in the potential money supply, that is un-earned, un-product driven, non-GNP expanding currency. Any ECON 101 student would understand that, given that there is really no solid basis for the value of money anymore, each individual dollar in the previous money supply is now worth, aggregated, $700 billion less.

    Crap. We're all screwed - unless of course I can find a way, before Friday, to buy an overpriced house, at 19% APR, that I can't afford, in a bad part of town....

    And the EU, I don't even want to think about that.

    I covet any comments and corrections on how I understand things. I'm going to try to get some sleep, but that's probably not very likely.

    H

    posted on 10/1/2008 10:56:57 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]
  • Blog reactions
  •  Tuesday, July 22, 2008

    Recently I had to make an .mdb file accessible for download after authentication and couldn't allow a direct link to the file. We had written a similar handler for .xls and others (.csv, etc...) - we sent back a few headers to set the file name and the mime type and then server.transfer'd to stream out the binary file.

    Turns out that IIS maps .mdb files to the aspnet_isapi.dll executable by default (in fact on the server we were testing it was also mapped to a perl interpreter... go figure) , making server.transfer cough. We were receiving the following error when trying to do the transfer:

    System.Web.HttpException: Error executing child request for /{ourdirectory}/{ourfilename}.mdb

    [HttpException (0x80004005): Error executing child request for /{ourdirectory}/{ourfilename}.]
       System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +2672379
       System.Web.HttpServerUtility.Execute(String path, TextWriter writer, Boolean preserveForm) +819
       System.Web.HttpServerUtility.Transfer(String path, Boolean preserveForm) +57
       System.Web.HttpServerUtility.Transfer(String path) +35
       {mycontrol}.Page_Load(Object sender, EventArgs e) in {path to my control file}.cs:33
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
       System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
       System.Web.UI.Control.OnLoad(EventArgs e) +99
       System.Web.UI.Control.LoadRecursive() +50
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627
    

    One of the options that we found was to simply remove the mapping in IIS, but then I ran into the problem of not being able to remove the mapping from the ASP.NET Development Server (at least in a way I could figure out easily). So, option 2 presented itself and we found it to be the best solution for both situations. Simply add the following in the <httpHandlers> section of your web.config:

    <remove verb="*" path="*.mdb" />

    If you don't have an httpHandlers section of your web.config, it goes in as a subsection of <system.web>

    <system.web>
    <!-- ... other stuff .. -->
    <httpHandlers>
    <remove verb="*" path="*.mdb" />
    </httpHandlers>
    <!-- ... other stuff ... -->
    </system.web>

    No more problems with code like the following:

    Response.ContentType = "application/octet-stream";
    Response.AddHeader("Content-Disposition", "attachment; filename=" + myFileName);
    Response.Flush();
    Server.Transfer(baseVirtualPath + myFileName);

    No my dev environment using Asp.Net Development Server had the same settings that the IIS 6 app had, so I could test and debug properly.

    Some helpful links that helped me solve the problem:

    http://www.eggheadcafe.com/software/aspnet/29460604/iis-6-wont-serve-mdb-fil.aspx
    http://forums.asp.net/p/1022569/1393806.aspx

    posted on 7/22/2008 4:38:33 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]
  • Blog reactions
  •  Monday, July 14, 2008

    I recently developed an application using Linq to Sql against SQL Express for my development environment. Initially, I was under the impression that it would be running in a SQL 2K5 production environment, but at my first deliverable discovered that I was going to have to port back to SQL 2000 prior to delivery.

    I thought at first that the only real changes I would have to make is reducing my varchar(max) types to the 2K5 upper limit and continue on, but discovered some pretty severe limitations to using Linq To SQL against SQL 2000.

    To access my LTS objects and methods, I wrapped everything up into a data layer that returned either single enties or IQueryable for multiple result sets, this in turn was consumed by my business layer which generally converted to lists or something that made a little more since to the presentation. On my port back, IQueryable seems to be where I ran into the problems. I was running into errors like the following:

    Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.

    Cannot translate expression to SQL for this server version.Translation would contain an expression of type Text, NText or Image in a SELECT DISTINCT clause

    Cannot translate expression to SQL for this server version

    Using SQL 2000 as the back-end doesn't allow me to do complex queries when the results contain nText or binary data as the derived sql makes extensive use of DISTINCT. Against SQL Express I had become accustomed to chaining together multiple IQueryable methods and then calling my datacontext to execute a single method. Now, I found myself having to make use of .ToList in virtually every complex query that involved a table at any join level that contained a BLOB. Lots and lots of junk across the wire...

    I still don't have a workable solution to allowing IQueryable to be replacement for collections and am in the process of combining methods anywhere that IQueryable no longer makes sense which is tedious and hopefully will be rendered unnecessary.

    That was a lot of lead up to what I really wanted to post - The limitations of SQL Server Express...

    For ages (at least several months), I have been developing against SQL Express and find it easy to use, light weight and very capable. However, I had never before considered the possibility that SQL Express could be a viable dbms, especially in a production environment. My application is complex, but not huge.

    The limitations of SQL Express are simply resource limits and not functional limits. As long as my db is smaller than 4GB in size (if I manage my log files well, there is no reason it shouldn't be) and doesn't require more than 1 CPU and 1 GB of RAM, SQL Express should be a fully capable and possibly even desirable alternative to the enterprise editions of even SQL 2005. These are not hardware limits, but resource limits constrained by the application itself. This means that SQL Express could probably live nicely on a web server and that the db service, out of the box, wouldn't grab an excessive share of resources.

    Using SQL Express would help me to avoid extensive re-writes and would allow the client to install without any additional software purchases. I covet any feedback on your experiences using SQL Express in a production environment and any feedback in general about this post.

    In addition, here are some links I found useful to finding the source of my problem in the first place:

    H

    posted on 7/14/2008 1:53:44 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]
  • Blog reactions