-
-
Save speier/6037842 to your computer and use it in GitHub Desktop.
using System.Web.Mvc; | |
using System.Web.Routing; | |
namespace Portal.Common.EmbeddedResources | |
{ | |
public class EmbeddedResourcesController : Controller | |
{ | |
public static void RegisterRoutes() | |
{ | |
RouteTable.Routes.InsertRoute( | |
"Content", | |
"Content/{*virtualPath}", | |
new { controller = "EmbeddedResources", action = "Index" }, | |
typeof(EmbeddedResourcesController).Namespace | |
); | |
RouteTable.Routes.InsertRoute( | |
"Scripts", | |
"Scripts/{*virtualPath}", | |
new { controller = "EmbeddedResources", action = "Index" }, | |
typeof(EmbeddedResourcesController).Namespace | |
); | |
RouteTable.Routes.InsertRoute( | |
"Templates", | |
"Templates/{*virtualPath}", | |
new { controller = "EmbeddedResources", action = "Index" }, | |
typeof(EmbeddedResourcesController).Namespace | |
); | |
} | |
public ActionResult Index(string virtualPath) | |
{ | |
var virtualFile = EmbeddedResourcesManager.GetEmbeddedResourceFile(virtualPath); | |
if (virtualFile == null) | |
{ | |
Response.StatusCode = 404; | |
return null; | |
} | |
return File(virtualFile.Open(), EmbeddedResourceTypes.GetContentType(virtualPath)); | |
} | |
} | |
} |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Reflection; | |
using System.Web; | |
using System.Web.Hosting; | |
namespace Portal.Common.EmbeddedResources | |
{ | |
public static class EmbeddedResourcesManager | |
{ | |
public static IEnumerable<EmbeddedResourceItem> EmbeddedResources { get; private set; } | |
static EmbeddedResourcesManager() | |
{ | |
EmbeddedResources = GetEmbeddedResources(); | |
} | |
public static void Init() | |
{ | |
HostingEnvironment.RegisterVirtualPathProvider(new EmbeddedViewProvider()); | |
} | |
public static bool IsEmbeddedResource(string virtualPath) | |
{ | |
var relativePath = VirtualPathUtility.ToAppRelative(virtualPath); | |
return ContainsEmbeddedResource(relativePath); | |
} | |
public static bool IsEmbeddedView(string virtualPath) | |
{ | |
return IsEmbeddedResource(virtualPath) && virtualPath.Contains("/Views/", StringComparison.InvariantCultureIgnoreCase); | |
} | |
public static bool ContainsEmbeddedResource(string virtualPath) | |
{ | |
var foundResource = FindEmbeddedResource(virtualPath); | |
return (foundResource != null); | |
} | |
public static EmbeddedResourceItem FindEmbeddedResource(string virtualPath) | |
{ | |
var name = GetNameFromPath(virtualPath); | |
var fileName = Path.GetFileName(virtualPath); | |
return string.IsNullOrEmpty(name) | |
? null | |
: EmbeddedResources.FirstOrDefault(r => r.Name.EndsWith(name, StringComparison.InvariantCultureIgnoreCase)); | |
} | |
public static Stream GetManifestResourceStream(string virtualPath) | |
{ | |
var embeddedResource = FindEmbeddedResource(virtualPath); | |
if (embeddedResource == null) | |
return null; | |
var assembly = GetAssemblies().FirstOrDefault(a => a.FullName.Equals(embeddedResource.AssemblyFullName, StringComparison.InvariantCultureIgnoreCase)); | |
return (assembly == null) ? null : assembly.GetManifestResourceStream(embeddedResource.Name); | |
} | |
public static EmbeddedResourceFile GetEmbeddedResourceFile(string virtualPath) | |
{ | |
var manifestResourceStream = GetManifestResourceStream(virtualPath); | |
return (manifestResourceStream == null) ? null : new EmbeddedResourceFile(virtualPath, manifestResourceStream); | |
} | |
public static string GetManifestResourceString(string virtualPath) | |
{ | |
var resourceFile = GetEmbeddedResourceFile(virtualPath); | |
return (resourceFile == null) ? string.Empty : new StreamReader(resourceFile.Open()).ReadToEnd(); | |
} | |
public static string GetNameFromPath(string virtualPath) | |
{ | |
if (string.IsNullOrEmpty(virtualPath)) | |
return null; | |
return virtualPath.Replace("~", string.Empty).Replace("/", "."); | |
} | |
private static IEnumerable<EmbeddedResourceItem> GetEmbeddedResources() | |
{ | |
var assemblies = GetAssemblies(); | |
if (assemblies == null || assemblies.Count() == 0) | |
return null; | |
var embeddedResources = new List<EmbeddedResourceItem>(); | |
foreach (var assembly in assemblies) | |
{ | |
var names = GetNamesOfAssemblyResources(assembly); | |
if (names == null || names.Length == 0) | |
continue; | |
var validNames = from name in names | |
let ext = Path.GetExtension(name) | |
where EmbeddedResourceTypes.Contains(ext) || name.ToLowerInvariant().Contains(".views.") | |
select name; | |
foreach (var name in validNames) | |
{ | |
embeddedResources.Add(new EmbeddedResourceItem { Name = name, AssemblyFullName = assembly.FullName }); | |
} | |
} | |
return embeddedResources; | |
} | |
private static IEnumerable<Assembly> GetAssemblies() | |
{ | |
try | |
{ | |
return AppDomain.CurrentDomain.GetAssemblies(); | |
} | |
catch | |
{ | |
return null; | |
} | |
} | |
private static string[] GetNamesOfAssemblyResources(Assembly assembly) | |
{ | |
// GetManifestResourceNames will throw a NotSupportedException when run on a dynamic assembly | |
try | |
{ | |
return assembly.GetManifestResourceNames(); | |
} | |
catch | |
{ | |
return new string[] { }; | |
} | |
} | |
} | |
public class EmbeddedResourceItem | |
{ | |
public string Name { get; set; } | |
public string AssemblyFullName { get; set; } | |
} | |
public class EmbeddedResourceFile : VirtualFile | |
{ | |
private readonly Stream _manifestResourceStream; | |
public EmbeddedResourceFile(string virtualPath, Stream manifestResourceStream) : | |
base(virtualPath) | |
{ | |
_manifestResourceStream = manifestResourceStream; | |
} | |
public override Stream Open() | |
{ | |
return _manifestResourceStream; | |
} | |
} | |
} |
using System.Collections.Generic; | |
using System.IO; | |
namespace Portal.Common.EmbeddedResources | |
{ | |
public static class EmbeddedResourceTypes | |
{ | |
public static string GetContentType(string path) | |
{ | |
return MimeTypes[Path.GetExtension(path)]; | |
} | |
public static bool Contains(string extension) | |
{ | |
return MimeTypes.ContainsKey(extension.ToLowerInvariant()); | |
} | |
public static readonly Dictionary<string, string> MimeTypes = new Dictionary<string, string> | |
{ | |
{".js", "text/javascript"}, | |
{".css", "text/css"}, | |
{".gif", "image/gif"}, | |
{".png", "image/png"}, | |
{".jpg", "image/jpeg"}, | |
{".xml", "application/xml"}, | |
{".txt", "text/plain"}, | |
{".html", "text/html"} | |
}; | |
} | |
} |
using System; | |
using System.Collections; | |
using System.Net; | |
using System.Web; | |
using System.Web.Caching; | |
using System.Web.Hosting; | |
namespace Portal.Common.EmbeddedResources | |
{ | |
public class EmbeddedViewProvider : VirtualPathProvider | |
{ | |
public override bool FileExists(string virtualPath) | |
{ | |
return base.FileExists(virtualPath) || EmbeddedResourcesManager.IsEmbeddedView(virtualPath); | |
} | |
public override VirtualFile GetFile(string virtualPath) | |
{ | |
if (base.FileExists(virtualPath)) | |
return base.GetFile(virtualPath); | |
try | |
{ | |
return EmbeddedResourcesManager.GetEmbeddedResourceFile(virtualPath); | |
} | |
catch | |
{ | |
throw new HttpException((int)HttpStatusCode.NotFound, "Embedded resource not found."); | |
} | |
} | |
public override CacheDependency GetCacheDependency(string virtualPath, | |
IEnumerable virtualPathDependencies, DateTime utcStart) | |
{ | |
return EmbeddedResourcesManager.IsEmbeddedResource(virtualPath) | |
? null | |
: base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); | |
} | |
} | |
} |
I got this to work by adding the following to my AreaRegistration file where i map by routes and removing it from the class shown above.
RouteTable.Routes.InsertRoute(
"Content",
"Content/{*virtualPath}",
new { controller = "EmbeddedResources", action = "Index" },
typeof(EmbeddedResourcesController).Namespace
);
RouteTable.Routes.InsertRoute(
"Scripts",
"Scripts/{*virtualPath}",
new { controller = "EmbeddedResources", action = "Index" },
typeof(EmbeddedResourcesController).Namespace
);
RouteTable.Routes.InsertRoute(
"Templates",
"Templates/{*virtualPath}",
new { controller = "EmbeddedResources", action = "Index" },
typeof(EmbeddedResourcesController).Namespace
);
however I had to make slight changes,
InsertRoute changed to MapRoute and the line with typeof(EmbeddedResourcesController).Namespace
had to be changed to: new[] {typeof (EmbeddedResourcesController).Namespace}
RouteTable.Routes.InsertRoute(
"Content",
"Content/{*virtualPath}",
new { controller = "EmbeddedResources", action = "Index" },
typeof(EmbeddedResourcesController).Namespace
);
Mine looks like
context.MapRoute(
"Content",
"Content/{*virtualPath}",
new { controller = "EmbeddedResources", action = "Index" },
new[] {typeof (EmbeddedResourcesController).Namespace}
);
Then I can access any files through the url:
http:/mysite.com/EmbeddedResources/index/?virtualPath=my.css
If you want to access other folders resources, just copy and change "Content/{_virtualPath}" to your other folder like "Scripts/{_virtualPath}".
Then use
http:/mysite.com/EmbeddedResources/index/?virtualPath=myscript.js
It's possible to get aspx and masterpage files from a embeddet resource with this code?
Can you let me know how to use it? I tried your code snippet but it doesn't work.
I have scripts, cshtml and other embedded files in an assembly named MyAssembly.
So I tried following urls to see if it works:
/Content/MyAssembly.Folder.Web.Views.Home.Index.cshtml
/Scripts/MyAssembly.Folder.Web.Scripts/Jquery.js