From 6c8485b1efe35f681740230646e0fa20df703d58 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 4 Feb 2014 06:34:34 -0800 Subject: [PATCH] Removing VirtualFileSystem from Razor * Paths rooted by a leading slash (e.g. /foo) are correctly resolved by the PhysicalFileSystem. This change is an experiment to determine if we can get away with not having virtual paths in WebFx. * Additionally removing types (MetadataVirtualPathViewFactory, VirtualPathAttribute) that are currently unused. --- samples/MvcSample/HomeController.cs | 4 +- samples/MvcSample/Startup.cs | 1 - samples/MvcSample/Views/Home/MyView.cshtml | 2 +- .../IRouteData.cs | 2 +- .../Resources.Designer.cs | 83 ++++++++++++ src/Microsoft.AspNet.Mvc.Razor/Resources.resx | 123 ++++++++++++++++++ .../ViewEngine/IVirtualFileSystem.cs | 8 -- .../MetadataVirtualPathViewFactory.cs | 51 -------- ...ViewFactory.cs => PathBasedViewFactory.cs} | 4 +- .../ViewEngine/RazorViewEngine.cs | 48 +++++-- .../ViewEngine/VirtualFile.cs | 48 ------- .../ViewEngine/VirtualFileSystem.cs | 48 ------- .../ViewEngine/VirtualPathAttribute.cs | 15 --- 13 files changed, 247 insertions(+), 190 deletions(-) create mode 100644 src/Microsoft.AspNet.Mvc.Razor/Resources.Designer.cs create mode 100644 src/Microsoft.AspNet.Mvc.Razor/Resources.resx delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualFileSystem.cs delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/ViewEngine/MetadataVirtualPathViewFactory.cs rename src/Microsoft.AspNet.Mvc.Razor/ViewEngine/{VirtualPathViewFactory.cs => PathBasedViewFactory.cs} (82%) delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFile.cs delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFileSystem.cs delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathAttribute.cs diff --git a/samples/MvcSample/HomeController.cs b/samples/MvcSample/HomeController.cs index d9d6433504..3e298ca8df 100644 --- a/samples/MvcSample/HomeController.cs +++ b/samples/MvcSample/HomeController.cs @@ -5,9 +5,9 @@ namespace MvcSample { public class HomeController : Controller { - public string Index() + public IActionResult Index() { - return "Hello World"; + return View("MyView", User()); } public IActionResult Something() diff --git a/samples/MvcSample/Startup.cs b/samples/MvcSample/Startup.cs index a2a9dcd118..5fa0576dc1 100644 --- a/samples/MvcSample/Startup.cs +++ b/samples/MvcSample/Startup.cs @@ -28,7 +28,6 @@ namespace MvcSample string appRoot = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "..", "..", "..")); serviceProvider.AddInstance(new PhysicalFileSystem(appRoot)); - serviceProvider.Add(); serviceProvider.AddInstance(new MvcRazorHost("Microsoft.AspNet.Mvc.Razor.RazorView")); serviceProvider.Add(); serviceProvider.Add(); diff --git a/samples/MvcSample/Views/Home/MyView.cshtml b/samples/MvcSample/Views/Home/MyView.cshtml index 27f328ad83..c84e688d5b 100644 --- a/samples/MvcSample/Views/Home/MyView.cshtml +++ b/samples/MvcSample/Views/Home/MyView.cshtml @@ -1,6 +1,6 @@  @{ - Layout = "~/Views/Shared/_Layout.cshtml"; + Layout = "/Views/Shared/_Layout.cshtml"; ViewBag.Title = "Home Page"; } diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/IRouteData.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/IRouteData.cs index 3f18ae5675..a12b7ce57b 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/IRouteData.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/IRouteData.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.Routing { if (name.Equals("controller", StringComparison.OrdinalIgnoreCase)) { - return GetPartOrDefault(0, "HomeController"); + return GetPartOrDefault(0, "Home"); } else if (name.Equals("action", StringComparison.OrdinalIgnoreCase)) { diff --git a/src/Microsoft.AspNet.Mvc.Razor/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Razor/Resources.Designer.cs new file mode 100644 index 0000000000..9fde1c7a34 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Razor/Resources.Designer.cs @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34003 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Mvc.Razor +{ + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if (object.ReferenceEquals(resourceMan, null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Mvc.Razor.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Value cannot be null or empty.. + /// + internal static string ArgumentCannotBeNullOrEmpty + { + get + { + return ResourceManager.GetString("ArgumentCannotBeNullOrEmpty", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx new file mode 100644 index 0000000000..445b35c1ec --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Value cannot be null or empty. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualFileSystem.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualFileSystem.cs deleted file mode 100644 index 7cce40e47e..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualFileSystem.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Microsoft.Owin.FileSystems; - -namespace Microsoft.AspNet.Mvc.Razor -{ - public interface IVirtualFileSystem : IFileSystem - { - } -} diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/MetadataVirtualPathViewFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/MetadataVirtualPathViewFactory.cs deleted file mode 100644 index 6535c45574..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/MetadataVirtualPathViewFactory.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; - -namespace Microsoft.AspNet.Mvc.Razor -{ - public class MetadataVirtualPathViewFactory : IVirtualPathViewFactory - { - private readonly Dictionary _viewMetadata; - - public MetadataVirtualPathViewFactory(Assembly assembly) - { - var metadataType = assembly.GetType("ViewMetadata"); - if (metadataType != null) - { - object metadata = metadataType.GetRuntimeProperties().First(prop => prop.Name == "Metadata") - .GetValue(obj: null); - - _viewMetadata = new Dictionary((Dictionary)metadata, StringComparer.OrdinalIgnoreCase); - } - else - { -#if NET45 - // Code to support precompiled views generated via RazorGenerator - _viewMetadata = assembly.GetExportedTypes() - .Where(type => typeof(RazorView).IsAssignableFrom(type)) - .ToDictionary(type => GetVirtualPath(type), StringComparer.OrdinalIgnoreCase); -#endif - } - } - - public Task CreateInstance(string virtualPath) - { - Type type; - IView view = null; - if (_viewMetadata.TryGetValue(virtualPath, out type)) - { - view = (IView)Activator.CreateInstance(type); - } - return Task.FromResult(view); - } - - private static string GetVirtualPath(Type type) - { - VirtualPathAttribute attribute = type.GetTypeInfo().GetCustomAttribute(); - return attribute.VirtualPath; - } - } -} diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathViewFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/PathBasedViewFactory.cs similarity index 82% rename from src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathViewFactory.cs rename to src/Microsoft.AspNet.Mvc.Razor/ViewEngine/PathBasedViewFactory.cs index 387dcb8cb4..8917645389 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathViewFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/PathBasedViewFactory.cs @@ -6,10 +6,10 @@ namespace Microsoft.AspNet.Mvc.Razor { public class VirtualPathViewFactory : IVirtualPathViewFactory { - private readonly IVirtualFileSystem _fileSystem; + private readonly IFileSystem _fileSystem; private readonly IRazorCompilationService _compilationService; - public VirtualPathViewFactory(IVirtualFileSystem fileSystem, IRazorCompilationService compilationService) + public VirtualPathViewFactory(IFileSystem fileSystem, IRazorCompilationService compilationService) { _fileSystem = fileSystem; _compilationService = compilationService; diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs index 925d843395..694acfa1ac 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs @@ -9,8 +9,8 @@ namespace Microsoft.AspNet.Mvc.Razor { private static readonly string[] _viewLocationFormats = new[] { - "~/Views/{1}/{0}.cshtml", - "~/Views/Shared/{0}.cshtml", + "/Views/{1}/{0}.cshtml", + "/Views/Shared/{0}.cshtml", }; private readonly IActionDescriptorProvider _actionDescriptorProvider; private readonly IVirtualPathViewFactory _virtualPathFactory; @@ -41,19 +41,41 @@ namespace Microsoft.AspNet.Mvc.Razor viewName = actionDescriptor.ActionName; } - string controllerName = actionDescriptor.ControllerName; - var searchedLocations = new List(_viewLocationFormats.Length); - for (int i = 0; i < _viewLocationFormats.Length; i++) + if (String.IsNullOrEmpty(viewName)) { - string path = String.Format(CultureInfo.InvariantCulture, _viewLocationFormats[i], viewName, controllerName); - IView view = await _virtualPathFactory.CreateInstance(path); - if (view != null) - { - return ViewEngineResult.Found(view); - } - searchedLocations.Add(path); + throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, "viewName"); } - return ViewEngineResult.NotFound(searchedLocations); + + bool nameRepresentsPath = IsSpecificPath(viewName); + + if (nameRepresentsPath) + { + IView view = await _virtualPathFactory.CreateInstance(viewName); + return view != null ? ViewEngineResult.Found(view) : + ViewEngineResult.NotFound(new[] { viewName }); + } + else + { + string controllerName = actionDescriptor.ControllerName; + var searchedLocations = new List(_viewLocationFormats.Length); + for (int i = 0; i < _viewLocationFormats.Length; i++) + { + string path = String.Format(CultureInfo.InvariantCulture, _viewLocationFormats[i], viewName, controllerName); + IView view = await _virtualPathFactory.CreateInstance(path); + if (view != null) + { + return ViewEngineResult.Found(view); + } + searchedLocations.Add(path); + } + return ViewEngineResult.NotFound(searchedLocations); + } + } + + private static bool IsSpecificPath(string name) + { + char c = name[0]; + return (name[0] == '/'); } } } diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFile.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFile.cs deleted file mode 100644 index fe1790d09a..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFile.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.IO; -using Microsoft.Owin.FileSystems; - -namespace Microsoft.AspNet.Mvc.Razor -{ - public class VirtualFile : IFileInfo - { - private readonly string _virtualPath; - private readonly IFileInfo _underlyingFileInfo; - - public VirtualFile(string virtualPath, IFileInfo underlyingFileInfo) - { - _virtualPath = virtualPath; - _underlyingFileInfo = underlyingFileInfo; - } - - public Stream CreateReadStream() - { - return _underlyingFileInfo.CreateReadStream(); - } - - public bool IsDirectory - { - get { return _underlyingFileInfo.IsDirectory; } - } - - public DateTime LastModified - { - get { return _underlyingFileInfo.LastModified; } - } - - public long Length - { - get { return _underlyingFileInfo.Length; } - } - - public string Name - { - get { return _underlyingFileInfo.Name; } - } - - public string PhysicalPath - { - get { return _virtualPath; } - } - } -} diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFileSystem.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFileSystem.cs deleted file mode 100644 index 511e2181e1..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualFileSystem.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Owin.FileSystems; - -namespace Microsoft.AspNet.Mvc.Razor -{ - public class VirtualFileSystem : IVirtualFileSystem - { - private readonly IFileSystem _fileSystem; - - public VirtualFileSystem(IFileSystem fileSystem) - { - _fileSystem = fileSystem; - } - - public bool TryGetFileInfo(string subpath, out IFileInfo fileInfo) - { - string translated = TranslatePath(subpath); - if (_fileSystem.TryGetFileInfo(translated, out fileInfo)) - { - fileInfo = new VirtualFile(subpath, fileInfo); - return true; - } - return false; - } - - public bool TryGetDirectoryContents(string subpath, out IEnumerable contents) - { - string translated = TranslatePath(subpath); - if (_fileSystem.TryGetDirectoryContents(translated, out contents)) - { - contents = contents.Select(c => new VirtualFile(subpath + '/' + c.Name, c)); - return true; - } - return false; - } - - private static string TranslatePath(string path) - { - if (path.StartsWith("~/", StringComparison.Ordinal)) - { - path = path.Substring(2); - } - return path; - } - } -} diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathAttribute.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathAttribute.cs deleted file mode 100644 index 67109c49ae..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Microsoft.AspNet.Mvc.Razor -{ - [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] - public class VirtualPathAttribute : Attribute - { - public VirtualPathAttribute(string virtualPath) - { - VirtualPath = virtualPath; - } - - public string VirtualPath { get; private set; } - } -}