-
-
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