Contact
Send mail to the author(s) Email Me

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Sign In
Navigation

Tag Cloud
.NET Framework (33) AJAX (9) ASP.NET (16) ASP.NET MVC (3) Azure (1) C# (35) Cloud (3) Database (7) Dev Community (2) Dev Tools (7) Enterprise Library (2) Extensions (1) Futures (2) General (6) IIS (1) Infrastructure (1) Javascript (7) LINQ (2) Mobile (1) MSDTC (6) Queuing (1) Quotes (5) SQL (5) Transactions (6) Visual Studio (3) WAS (2) WCF (24) WIF (1)

Archive
<January 2007>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Categories

Blogroll
Home Feed your aggregator (RSS 2.0)
# Wednesday, January 24, 2007

In preparing for a recent business trip, I decided to lookup the TSA's current prohibited items list.   You can download the list at http://www.tsa.gov/assets/pdf/prohibited-and-permitted-items.pdf.   Does anyone else find an item on this list that doesn't make sense?

Wednesday, January 24, 2007 2:52:53 AM (Eastern Standard Time, UTC-05:00)  #    Comments [3]   General  | 
# Monday, November 06, 2006

I frequently store documents in the database for my ASP.NET apps, eliminating web farm complications with shared drives, permissions, etc.  When uploading a file, my Document class reads the uploaded file, zips the file with SharpZipLib, and inserts/updates in the database.   When opening a file, I have always used an ASPX page that uses the Document class to unzip the file, and then changes the Content-Disposition and ContentType headers, and then does a BinaryWrite to the Response object to display the file.

I have been using Handlers a lot lately, and figured that it was time to make this process a little more elegant.  If you've never written a handler, it's quite simple.  You need to make a web.config change, and add a new class that implementts IHttpHandler.  All of the work is done in ProcessRequest.  Using the default .ashx extension for the handler eliminates the need to make any changes in IIS.  I thought about changing the handler to accept all requests with known file extensions with the document ID as the filename, like 3383.pdf.  I just figured that using the default extnesion would be easier.   Laziness or efficiency, you decide.  Check out the code.

In <system.web> in web.config:


<httpHandlers>
   
<add verb="*" path="DocumentHandler.ashx" type="TestingWebApp.DocumentHandler, TestingWebApp" />
</httpHandlers>

DocumentHandler.cs:


using System;
using System.Web;

namespace TestingWebApp
{
    public class DocumentHandler : IHttpHandler
    {
        private int DocumentId
        {
            get
            {
                if(System.Web.HttpContext.Current.Request.QueryString["DocumentId"] != null && System.Web.HttpContext.Current.Request.QueryString["DocumentId"].ToString().Length > 0)
                    return Convert.ToInt32(System.Web.HttpContext.Current.Request.QueryString["DocumentId"]);
                else
                    throw new ApplicationException("Document Handler requires a DocumentId");
            }
        }

        #region IHttpHandler Members

        public void ProcessRequest(System.Web.HttpContext context)
        {
            context.Response.Cache.SetCacheability(HttpCacheability.Public);
            context.Response.BufferOutput = false;
            
            Document document = Document.GetDocumentByDocumentId(this.DocumentId);

            byte[] buffer = document.UnzippedBinary;
            context.Response.ContentType = document.ContentType;
            context.Response.OutputStream.Write(buffer, 0, buffer.Length);
        }

        public bool IsReusable
        {
            get { return true; }
        }

        #endregion
    }
}
Monday, November 06, 2006 11:31:15 PM (Eastern Standard Time, UTC-05:00)  #    Comments [5]   .NET Framework | ASP.NET | C# | Database  | 
# Sunday, November 05, 2006

The starter kit already allowed individual file upload, and batch upload from a directory which requires files to be moved to Upload directory by FTP.  The starter kit also stores the images in the database. While I prefer this method for most files, I don't prefer it for images. I changed a few methods to store the images in an images folder, and modified the image serving handler accordingly.  The album page load time is a fraction of what it was with images in the database.

I also created an XP Publishing Wizard that allows any user with credentials to create/choose an album, and upload images from Windows XP. The beauty of the XPPW is that it can resize the images before uploading. That way all of us with 10 megapixel cameras no longer have to spend any extra time resizing to prevent reaching a web host storage quota.

A few articles helped me figure this stuff out:

Creating the wizard was easy enough.  You first need to create a registry entry in the following format:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\PublishingWizard\PublishingWizard\Providers\Your Photo Gallery]
"displayname"="Your Photo Gallery"
"description"="Online Photo Albums"
"href"="http://www.yoursite.net/XPPublish.aspx"
"icon"="http://www.yoursite.net/favicon.ico"

Next is a single aspx page that accepts the files.  The page handles user login, album creation/selection, and accepts multiple files in a single form post.  All the hard work is done by some javascript methods that handle the XML sent from Windows XP.  The javascript looks like this:

        <script language='javascript'>
            function startUpload()
            {
                var xml = window.external.Property("TransferManifest");
                var files = xml.selectNodes("transfermanifest/filelist/file");
                var albumId = document.getElementById("Album").value;

                for (i = 0; i < files.length; i++)
                {
                    var postTag = xml.createNode(1, "post", "");
                    postTag.setAttribute("href", "http://yoursite.net/XPPublish.aspx");

                    postTag.setAttribute("name", "userpicture");

                    var dataTag = xml.createNode(1, "formdata", "");
                    dataTag.setAttribute("name", "MAX_FILE_SIZE");
                    dataTag.text = "10000000";                    
                    postTag.appendChild(dataTag);
                    
                    var dataTag1 = xml.createNode(1, "formdata", "");
                    dataTag1.setAttribute("name", "btnUpload");
                    dataTag1.text = "Save";
                    postTag.appendChild(dataTag1);
                    
                    var dataTag2 = xml.createNode(1, "formdata", "");
                    dataTag2.setAttribute("name", "hidAlbumId");
                    dataTag2.text = albumId;
                    postTag.appendChild(dataTag2);

                    files.item(i).appendChild(postTag);
                }
                
                var uploadTag = xml.createNode(1, "uploadinfo", "");
                uploadTag.setAttribute("friendlyname", "Family Photo Gallery");
                var htmluiTag = xml.createNode(1, "htmlui", "");
                htmluiTag.text = "http://yoursite.net/Personal/Albums/Photos.aspx?AlbumID=" + albumId;
                uploadTag.appendChild(htmluiTag);

                xml.documentElement.appendChild(uploadTag);

                window.external.Property("TransferManifest") = xml;
                window.external.SetWizardButtons(true,true,true);
                document.getElementById("divContent").innerHtml = xml;
                window.external.FinalNext();
            }

            function OnBack()
            {
                window.external.FinalBack();
                window.external.SetWizardButtons(false,true,false);
            }

            function OnNext()
            {
                if (document.getElementById("divLogin"))
                {
                    document.getElementById("LoginArea_Login1_LoginButton").click();
                }
                else
                {
                    startUpload();
                }
            }

            function OnCancel()
            {
            }

            function window.onload()
            {
                window.external.SetHeaderText('Photo Gallery','Your Photos');
                window.external.SetWizardButtons(true,true,false);
            }
        </script>

In case you haven't seen the XP Publishing Wizard in action, check out these screenshots:

 

 

 

 

 

 

 

 

 

Sunday, November 05, 2006 9:35:38 PM (Eastern Standard Time, UTC-05:00)  #    Comments [6]   ASP.NET | Javascript  | 
# Saturday, November 04, 2006

I record only a few shows on my DVR.  While fast-forwarding through commercials during last night's Battlestar Galactica, I saw a familiar image and had to rewind.  Ahhh... and then it appeared as a voice said "Tonight's episode is brought to you by Microsoft Visual Studio 2005."  Seeing that made me feel twice as dorky for watching that show.

Saturday, November 04, 2006 4:13:48 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]   General  | 
# Tuesday, August 29, 2006
Tuesday, August 29, 2006 8:51:51 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]   .NET Framework | C#  | 
# Monday, August 28, 2006

The 2006 Jacksonville Code Camp was great. I spent the whole day in the Code Countdown room cranking our code for a worthy cause. Shawn Weisfeld, David Silverlight and I wrote a web app from scratch with ASP.NET for a non-profit organization in Pennsylvania. I'm happy that I was able to participate in the first Code Countdown, and help a non-profit organization. You can volunteer to help out in a similar way by checking out David Silverlight's site, www.nonprofitways.com.

Monday, August 28, 2006 8:53:50 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]   General  | 
# Tuesday, November 08, 2005

This 2.1 update includes over 60 improvements, including new support for .NET 2.0 and Visual Studio 2005. VistaDB is a small-footprint, embedded SQL database alternative to Jet/Access, MSDE and SQL Server Express 2005 that enables developers to build .NET 1.1 and .NET 2.0 applications. Features SQL-92 support, small 500KB embedded footprint, free 2-User VistaDB Server for remote TCP/IP data access, royalty free distribution for both embedded and server, Copy 'n Go! deployment, managed ADO.NET Provider, data management and data migration tools. Free trial is available for download.

Tuesday, November 08, 2005 9:55:01 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]   .NET Framework | C# | Database  | 
Copyright © 2010 Scott Klueppel. All rights reserved.