diff --git a/src/Orchard.Web/Global.asax.cs b/src/Orchard.Web/Global.asax.cs index 2157b1767..066d1fe13 100644 --- a/src/Orchard.Web/Global.asax.cs +++ b/src/Orchard.Web/Global.asax.cs @@ -3,13 +3,12 @@ using System.IO; using System.Linq; using System.Reflection; using System.Web; +using System.Web.Hosting; using System.Web.Mvc; using System.Web.Routing; using Autofac; -using Autofac.Builder; -using Autofac.Integration.Web; -using Autofac.Integration.Web.Mvc; using Orchard.Environment; +using Orchard.Environment.Extensions.Loaders; namespace Orchard.Web { // Note: For instructions on enabling IIS6 or IIS7 classic mode, @@ -32,6 +31,7 @@ namespace Orchard.Web { RegisterRoutes(RouteTable.Routes); + HostingEnvironment.RegisterVirtualPathProvider(new WebFormsExtensionsVirtualPathProvider()); _host = OrchardStarter.CreateHost(MvcSingletons); _host.Initialize(); @@ -101,6 +101,5 @@ namespace Orchard.Web { builder.RegisterInstance(ModelMetadataProviders.Current); builder.RegisterInstance(ViewEngines.Engines); } - } } diff --git a/src/Orchard/Environment/Extensions/Loaders/WebFormsExtensionsVirtualFile.cs b/src/Orchard/Environment/Extensions/Loaders/WebFormsExtensionsVirtualFile.cs new file mode 100644 index 000000000..11ef6a4c6 --- /dev/null +++ b/src/Orchard/Environment/Extensions/Loaders/WebFormsExtensionsVirtualFile.cs @@ -0,0 +1,51 @@ +using System.IO; +using System.Reflection; +using System.Web.Hosting; + +namespace Orchard.Environment.Extensions.Loaders { + public class WebFormsExtensionsVirtualFile : VirtualFile { + private readonly Assembly _assembly; + private readonly VirtualFile _actualFile; + + public WebFormsExtensionsVirtualFile(string virtualPath, Assembly assembly, VirtualFile actualFile) + : base(virtualPath) { + _assembly = assembly; + _actualFile = actualFile; + } + + public override string Name { + get { + return _actualFile.Name; + } + } + + public override bool IsDirectory { + get { + return _actualFile.IsDirectory; + } + } + + public override Stream Open() { + var reader = new StreamReader(_actualFile.Open()); + var memoryStream = new MemoryStream(); + int length; + using (var writer = new StreamWriter(memoryStream)) { + + bool assemblyDirectiveAdded = false; + for (var line = reader.ReadLine(); line != null; line = reader.ReadLine()) { + + if (!string.IsNullOrWhiteSpace(line) && !assemblyDirectiveAdded) { + line += string.Format("<%@ Assembly Name=\"{0}\"%>", _assembly); + assemblyDirectiveAdded = true; + } + + writer.WriteLine(line); + } + writer.Flush(); + length = (int)memoryStream.Length; + } + var result = new MemoryStream(memoryStream.GetBuffer(), 0, length); + return result; + } + } +} diff --git a/src/Orchard/Environment/Extensions/Loaders/WebFormsExtensionsVirtualPathProvider.cs b/src/Orchard/Environment/Extensions/Loaders/WebFormsExtensionsVirtualPathProvider.cs new file mode 100644 index 000000000..39a81f0d0 --- /dev/null +++ b/src/Orchard/Environment/Extensions/Loaders/WebFormsExtensionsVirtualPathProvider.cs @@ -0,0 +1,77 @@ +using System; +using System.Linq; +using System.Web.Hosting; +using Orchard.FileSystems.Dependencies; + +namespace Orchard.Environment.Extensions.Loaders { + public class WebFormsExtensionsVirtualPathProvider : VirtualPathProvider { + private IDependenciesFolder _dependenciesFolder; + private const string _prefix1 = "~/Modules/"; + private const string _prefix2 = "/Modules/"; + + public WebFormsExtensionsVirtualPathProvider() { + } + + protected override void Initialize() { + base.Initialize(); + _dependenciesFolder = new DefaultDependenciesFolder(new DefaultVirtualPathProvider()); + } + + public override bool DirectoryExists(string virtualDir) { + return Previous.DirectoryExists(virtualDir); + } + + public override bool FileExists(string virtualPath) { + return Previous.FileExists(virtualPath); + } + + public override VirtualFile GetFile(string virtualPath) { + var actualFile = Previous.GetFile(virtualPath); + + var prefix = PrefixMatch(virtualPath); + if (prefix == null) + return actualFile; + + var extension = ExtensionMatch(virtualPath, ".ascx", ".aspx", ".master"); + if (extension == null) + return actualFile; + + var moduleName = ModuleMatch(virtualPath, prefix); + if (moduleName == null) + return actualFile; + + // It looks like we have a module name. Is this one of this modules + // with its assembly stored in the "App_Data/Dependencies" folder? + var assembly = _dependenciesFolder.LoadAssembly(moduleName); + if (assembly == null) + return actualFile; + + // Yes: we need to wrap the VirtualFile to add the <%@ Assembly Name=".."%> directive + // in the content. + return new WebFormsExtensionsVirtualFile(virtualPath, assembly, actualFile); + } + + private string ModuleMatch(string virtualPath, string prefix) { + var index = virtualPath.IndexOf('/', prefix.Length, virtualPath.Length - prefix.Length); + if (index < 0) + return null; + + var moduleName = virtualPath.Substring(prefix.Length, index - prefix.Length); + return (string.IsNullOrEmpty(moduleName) ? null : moduleName); + } + + private string ExtensionMatch(string virtualPath, params string[] extensions) { + return extensions + .FirstOrDefault(e => virtualPath.EndsWith(e, StringComparison.OrdinalIgnoreCase)); + } + + private string PrefixMatch(string virtualPath) { + if (virtualPath.StartsWith(_prefix1)) + return _prefix1; + if (virtualPath.StartsWith(_prefix2)) + return _prefix2; + return null; + + } + } +} \ No newline at end of file diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 129d4177f..1a902fbdc 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -341,6 +341,8 @@ + +