Created
July 19, 2013 09:16
-
-
Save speier/6037842 to your computer and use it in GitHub Desktop.
ASP.NET MVC embedded views and virtual path provider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"} | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's possible to get aspx and masterpage files from a embeddet resource with this code?