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