2

I've been asked to see if it's possible to prevent the Content directory from appearing as part of the url in an Asp.Net MVC 3.0 application. For example at present when I want to view an image in the sub directory of the Content folder the url is as follows:

http://localhost:[port]/Content/sub/test.bmp

While we are looking to display it simply as follows:

http://localhost:[port]/sub/test.bmp

Test.bmp will still physically exist in the sub directory of the Content folder on the server we just want to hide the Content part.

Any suggestions? I can see ways of masking controllers but not directories.

2 Answers 2

5

You could write a controller action which will take as an argument the filename and serve it from the sub directory. Then configure a route for this controller action so that it is accessible with sub/{filename}.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Darin unfortunately sub is just an example there will be dozens of further directories that will be contained within the Content directory. This code will potentially be used as part of a Content Management System so the Content folder could contain practically anything.
@kh25, great, then you need to arguments to your controller action and the following route: {dir}/{file}
I'll have a look at this again later (I'm currently working on something else) are you suggesting using a redirect in the controller to load the url? If so won't this redirected url just contain the full path as before (including the Content dir). I'm new to MVC so you'll have to bear with me.
@kh25, no, I am not suggesting a redirect. I am suggesting you the controller action to read the requested file from the physical folder and then return File(...).
2

Solution is as follows (this is just the barebones code at the moment and needs to be tidied up):

Added this route to Global.asax :

routes.MapRoute("Content",
                "{dir}/{file}",
                new { controller = "Content", action = "LoadContent"});

Added this controller to handle the request:

namespace demos
{
   public class ContentController : Controller
    {
        public ActionResult LoadContent(string dir, string file)
        {
            string fileName = Server.MapPath(Url.Content("~/Content/" + dir)) 
            fileName += "\\" + file;            

            // stream file if exists    
            FileInfo info = new FileInfo(fileName);
            if (info.Exists)
                return File(info.OpenRead(), MimeType(fileName));


            // else return null - file not found
            return null;            
        }


        private string MimeType(string filename)
        {
            string mime = "application/octetstream";
            var extension = Path.GetExtension(filename);
            if (extension != null)
            {
               RegistryKey rk = Registry.ClassesRoot.OpenSubKey(extension.ToLower());

                if (rk != null && rk.GetValue("Content Type") != null)
                    mime = rk.GetValue("Content Type").ToString();
            }

            return mime;
        }
    }
}

1 Comment

That route code will break almost all routes after it, or be broken by the default routes before it. -1 If you fix the problem, I'll remove down vote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.