tags:

views:

1319

answers:

3

I have IIS 7.0 on my development machine and IIS 6.0 on my server. On my development machine I was able to set a handler map on a directory within my site called /ViewHtml/ and I mapped it to asp.net. In my global.asax I check the request sent to asp.net for /ViewHtml/ and I serve the appropriate html file(html version of a Doc, Power Point, or Excel file) located outside this apps virtual directory. I am doing it this way because all files are permission protected, we didn't want to put these files in are database due to scalability, and I need to hide the path to these file on the server. This all works in IIS 7.0 exactly how I would like it to. Although I have not been able to get my IIS 6.0 server configured to map all requests to that directory to asp.net.

Any ideas? Thanks Guys?

A: 

If I understand the problem correctly, it sounds like you need add a "Wildcard Application Mapping" for your virtual directory. In other words, you want to forward all requests to any file extension to ASP.NET's ISAPI extension.

To do so, open the properties of your virtual directory. On the Virtual Directory tab (Home Directory tab if it's a web site), click the Configuration... button. Click the Insert... button next to the bottom list box in the dialog that shows up. In this dialog, choose "%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" as the executable and make sure to un-check "Verify that file exists" checkbox, since the files to be requested don't live in your virtual directory.

I hope this helps!

Matt
Thanks Matt. I have tried this but I still get a 404 error when I try and show any pages through /ViewHtml/. /ViewHtml/ is a virtual directory in my projects virtual directory, I added a wildcard application map from /ViewHtml/ to aspnet_isapi.dll (asp.net) and unchecked verify that file exists , then restarted IIS. Did I miss something?
It sounds like you have everything right. Do you know if the code in your Global.asax file is running? Can you post a sample of the code in your Global.asax?
Matt
Thanks again for the quick response Matt. I can post the code if you think it will help. Because of the 404 error I was under the impression that IIS is still handling the request and not mapping it to Asp.net where the golbal would handle it in Application_BeginRequest function.
A: 

This is what I have in the Application_BeginRequest function in my global.

if (context.Request.Path.IndexOf(@"/ViewHtml/") > 0 )//Check path to see if we are serving local files { string[] args = context.Request.Path.Split('/');

                int lastArg = args.Count() - 1;//used to get last agrument from url file name
                int secondLastArg = args.Count() - 2;//used to get second last argument from url entity ID
                int thirdLastArgHistory = args.Count() - 3;//used to third last argument from url History file name
                int fourthLastArgHistory = args.Count() - 4;//used to third last argument from url History file name

                string fileNameFromUrl = args[lastArg];
                string entityId = args[secondLastArg];//Getting entity id from this location in url, should be valid if requesting a html page


                int Id = -1;
                try { int.TryParse(entityId, out Id); }
                catch { Id = -1; }

                Entity contentToView = null;
                EntityService srv = new EntityService();

                if (Id != -1)
                {

                    if (Id == 0)//Enitity Id didn't get valid Id from url, request must be for an item in an html page
                    {
                        //Get entity id from appropriate place in url when requesting an item for a page
                        entityId = args[thirdLastArgHistory];

                        try { int.TryParse(entityId, out Id); }
                        catch { Id = -1; }
                    }

                    if(Id != -1)
                        contentToView = srv.Get(Id);//Get content entity from parsed ID
                }

                //TODO check security to make sure logged in uer can see uploaded file

                string filePath = "";//Used to hold actual file path of file being requested

                if (context.Request.Path.IndexOf(@"/ViewHtml/FileHistory/") > 0)//Get html from files hisorty
                {
                    if (string.Equals(fileNameFromUrl, contentToView.Name))
                    {
                        string historyFileName = args[thirdLastArgHistory];//Get the history file name

                        //Create path for html page
                        filePath = ConfigurationSettings.AppSettings["Library Folder"] + contentToView.ContentExt.UploadedFileName +
                             @"\History\" + historyFileName + @"\Html\" +
                            contentToView.ContentExt.UploadedFileName  + ".html";
                    }
                    else//Create file path for item in page IE: jpg,gif, css, js
                    {
                        string historyFileName = args[fourthLastArgHistory];//Get the history file name
                        //Create files path from contentToView and "Library Files" path on server
                        filePath = ConfigurationSettings.AppSettings["Library Folder"] + contentToView.ContentExt.UploadedFileName + @"\History\" 
                         + historyFileName + @"\Html\" + args[secondLastArg] + @"\" + args[lastArg];

                    }
                }
                else//Get html for file
                {

                    if (string.Equals(fileNameFromUrl, contentToView.Name))
                    {
                        //Create path for html page
                        filePath = ConfigurationSettings.AppSettings["Library Folder"] + contentToView.ContentExt.UploadedFileName 
                            + @"\Html\" + contentToView.ContentExt.UploadedFileName + ".html";
                    }
                    else//Create file path for item in page IE jpg,gif, css, js
                    {
                        //Create files path from contentToView and "Library Files" path on server
                        filePath = ConfigurationSettings.AppSettings["Library Folder"] + contentToView.ContentExt.UploadedFileName +
                        @"\Html\" + args[secondLastArg] + @"\" + args[lastArg];

                    }
                }

                byte[] img = null;//hold img bytes to send
                string html = "";//hold html to send

                FileInfo file = new FileInfo(filePath);

                if (file.Exists)//
                {
                    string type = GetContentTypeFromExt(file.Extension);

                    switch (type)
                    {
                        case "image/jpeg":
                        case "image/gif":
                        case "image/png":
                            img = File.ReadAllBytes(filePath);
                            context.Response.Clear();
                            context.Response.AddHeader("Content-Length", file.Length.ToString());
                            context.Response.ContentType = type;
                            context.Response.BinaryWrite(img);
                            context.Response.End();
                            break;
                        case "text/html":
                        case "text/xml":
                        case "text/plain":
                            html = File.ReadAllText(filePath);
                            context.Response.Clear();
                            context.Response.AddHeader("Content-Length", file.Length.ToString());
                            context.Response.ContentType = type;
                            context.Response.Write(html);
                            context.Response.End();
                            break;
                        default:
                            break;
                    }

                }
A: 

I set up a web application using the same configuration you're using and I'm also getting the 404. I don't know why it works in IIS 7, but here's what I had to do to fix it.

Create a class that implements the System.Web.IHttpHandler class. move the the code from Application_BeginRequest to your implementation of IHttpHandler.ProcessRequest.

Now you just have to register your HTTP handler with ASP.NET. To do so add an entry in your Web.config at /configuration/system.web/httphandlers.

Web.config Example:

...
<httpHandlers>
    <clear />
    <add verb="*" path="*" type="namespace.classname, assemblyname" />
</httpHandlers>
...

That entry is telling ASP.NET to handle HTTP requests with any extension and any HTTP method by running the code in your HTTP hander. Note that I'm also clearing all the previously definded handlers (defined in the machine's web.config).

Note that you will still need the Application Mapping configured in IIS.

Matt
Thanks again Matt. This got it all working for me.