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.
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}
.
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;
}
}
}