diff --git a/Mvc.sln b/Mvc.sln
index 14f6eef714..ef7698c239 100644
--- a/Mvc.sln
+++ b/Mvc.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.21813.0
+VisualStudioVersion = 14.0.21901.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DAAE4C74-D06F-4874-A166-33305D2643CE}"
EndProject
@@ -51,6 +51,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Test",
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CompositeViewEngine", "test\WebSites\CompositeViewEngine\CompositeViewEngine.kproj", "{A853B2BA-4449-4908-A416-5A3C027FC22B}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RazorWebSite", "test\WebSites\RazorWebSite\RazorWebSite.kproj", "{B07CAF59-11ED-40E3-A5DB-E1178F84FA78}"
+EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ValueProvidersSite", "test\WebSites\ValueProvidersSite\ValueProvidersSite.kproj", "{14F79E79-AE79-48FA-95DE-D794EF4EABB3}"
EndProject
Global
@@ -263,6 +265,16 @@ Global
{A853B2BA-4449-4908-A416-5A3C027FC22B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A853B2BA-4449-4908-A416-5A3C027FC22B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A853B2BA-4449-4908-A416-5A3C027FC22B}.Release|x86.ActiveCfg = Release|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78}.Release|x86.ActiveCfg = Release|Any CPU
{14F79E79-AE79-48FA-95DE-D794EF4EABB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14F79E79-AE79-48FA-95DE-D794EF4EABB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14F79E79-AE79-48FA-95DE-D794EF4EABB3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -299,6 +311,7 @@ Global
{42CDBF4A-E238-4C0F-A416-44588363EB4C} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{5F945B82-FE5F-425C-956C-8BC2F2020254} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{A853B2BA-4449-4908-A416-5A3C027FC22B} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
+ {B07CAF59-11ED-40E3-A5DB-E1178F84FA78} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
{14F79E79-AE79-48FA-95DE-D794EF4EABB3} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
EndGlobalSection
EndGlobal
diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathViewFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/FileBasedRazorPageFactory.cs
similarity index 53%
rename from src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathViewFactory.cs
rename to src/Microsoft.AspNet.Mvc.Razor/FileBasedRazorPageFactory.cs
index 3a8884a404..0cdd72eddf 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/VirtualPathViewFactory.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/FileBasedRazorPageFactory.cs
@@ -3,22 +3,25 @@
using System;
using Microsoft.AspNet.Mvc.Core;
-using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor
{
- public class VirtualPathViewFactory : IVirtualPathViewFactory
+ ///
+ /// Represents a that creates instances
+ /// from razor files in the file system.
+ ///
+ public class FileBasedRazorPageFactory : IRazorPageFactory
{
private readonly IRazorCompilationService _compilationService;
private readonly ITypeActivator _activator;
private readonly IServiceProvider _serviceProvider;
private readonly IFileInfoCache _fileInfoCache;
- public VirtualPathViewFactory(IRazorCompilationService compilationService,
- ITypeActivator typeActivator,
- IServiceProvider serviceProvider,
- IFileInfoCache fileInfoCache)
+ public FileBasedRazorPageFactory(IRazorCompilationService compilationService,
+ ITypeActivator typeActivator,
+ IServiceProvider serviceProvider,
+ IFileInfoCache fileInfoCache)
{
_compilationService = compilationService;
_activator = typeActivator;
@@ -26,14 +29,16 @@ namespace Microsoft.AspNet.Mvc.Razor
_fileInfoCache = fileInfoCache;
}
- public IView CreateInstance([NotNull] string virtualPath)
+ ///
+ public RazorPage CreateInstance([NotNull] string viewPath)
{
- var fileInfo = _fileInfoCache.GetFileInfo(virtualPath);
+ var fileInfo = _fileInfoCache.GetFileInfo(viewPath.TrimStart('~'));
if (fileInfo != null)
{
var result = _compilationService.Compile(fileInfo);
- return (IView)_activator.CreateInstance(_serviceProvider, result.CompiledType);
+ var page = (RazorPage)_activator.CreateInstance(_serviceProvider, result.CompiledType);
+ return page;
}
return null;
diff --git a/src/Microsoft.AspNet.Mvc.Razor/IRazorViewActivator.cs b/src/Microsoft.AspNet.Mvc.Razor/IRazorPageActivator.cs
similarity index 60%
rename from src/Microsoft.AspNet.Mvc.Razor/IRazorViewActivator.cs
rename to src/Microsoft.AspNet.Mvc.Razor/IRazorPageActivator.cs
index e3b2966170..99eb83c493 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/IRazorViewActivator.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/IRazorPageActivator.cs
@@ -4,15 +4,15 @@
namespace Microsoft.AspNet.Mvc.Razor
{
///
- /// Provides methods to activate properties on a view instance.
+ /// Provides methods to activate properties on a instance.
///
- public interface IRazorViewActivator
+ public interface IRazorPageActivator
{
///
- /// When implemented in a type, activates an instantiated view.
+ /// When implemented in a type, activates an instantiated page.
///
- /// The view to activate.
- /// The for the view.
- void Activate(RazorView view, ViewContext context);
+ /// The page to activate.
+ /// The for the executing view.
+ void Activate(RazorPage page, ViewContext context);
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/IRazorPageFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/IRazorPageFactory.cs
new file mode 100644
index 0000000000..1953c83585
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor/IRazorPageFactory.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+namespace Microsoft.AspNet.Mvc.Razor
+{
+ ///
+ /// Defines methods that are used for creating instances at a given path.
+ ///
+ public interface IRazorPageFactory
+ {
+ ///
+ /// Creates a for the specified path.
+ ///
+ /// The path to locate the RazorPage.
+ /// The RazorPage instance if it exists, null otherwise.
+ RazorPage CreateInstance(string viewPath);
+ }
+}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Microsoft.AspNet.Mvc.Razor.kproj b/src/Microsoft.AspNet.Mvc.Razor/Microsoft.AspNet.Mvc.Razor.kproj
index 86c67fcad0..9d991f2d35 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Microsoft.AspNet.Mvc.Razor.kproj
+++ b/src/Microsoft.AspNet.Mvc.Razor/Microsoft.AspNet.Mvc.Razor.kproj
@@ -29,19 +29,20 @@
+
-
+
+
+
+
-
-
+
+
-
-
-
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs
index 0187e832a0..21ff13315a 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs
@@ -202,6 +202,22 @@ namespace Microsoft.AspNet.Mvc.Razor
return string.Format(CultureInfo.CurrentCulture, GetString("ViewCannotBeActivated"), p0, p1);
}
+ ///
+ /// '{0} must be set to access '{1}'.
+ ///
+ internal static string ViewContextMustBeSet
+ {
+ get { return GetString("ViewContextMustBeSet"); }
+ }
+
+ ///
+ /// '{0} must be set to access '{1}'.
+ ///
+ internal static string FormatViewContextMustBeSet(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("ViewContextMustBeSet"), p0, p1);
+ }
+
///
/// View '{0}' must have extension '{1}' when the view represents a full path.
///
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
similarity index 78%
rename from src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
rename to src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
index 2615dae58f..a869f01f8b 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
@@ -7,19 +7,25 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Security.Principal;
-using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Rendering;
-using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor
{
- public abstract class RazorView : IView
+ ///
+ /// Represents properties and methods that are needed in order to render a view that uses Razor syntax.
+ ///
+ public abstract class RazorPage
{
private readonly HashSet _renderedSections = new HashSet(StringComparer.OrdinalIgnoreCase);
private bool _renderedBody;
+ public RazorPage()
+ {
+ SectionWriters = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+
[Activate]
public IUrlHelper Url { get; set; }
@@ -40,7 +46,22 @@ namespace Microsoft.AspNet.Mvc.Razor
public string Layout { get; set; }
- protected TextWriter Output { get; set; }
+ ///
+ /// Gets the TextWriter that the page is writing output to.
+ ///
+ public virtual TextWriter Output
+ {
+ get
+ {
+ if (ViewContext == null)
+ {
+ var message = Resources.FormatViewContextMustBeSet("ViewContext", "Output");
+ throw new InvalidOperationException(message);
+ }
+
+ return ViewContext.Writer;
+ }
+ }
public virtual IPrincipal User
{
@@ -63,66 +84,11 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
- private string BodyContent { get; set; }
+ public string BodyContent { get; set; }
- private Dictionary SectionWriters { get; set; }
+ public Dictionary PreviousSectionWriters { get; set; }
- private Dictionary PreviousSectionWriters { get; set; }
-
- public virtual async Task RenderAsync([NotNull] ViewContext context)
- {
- SectionWriters = new Dictionary(StringComparer.OrdinalIgnoreCase);
- ViewContext = context;
-
- var contentBuilder = new StringBuilder(1024);
- using (var bodyWriter = new StringWriter(contentBuilder))
- {
- Output = bodyWriter;
-
- // The writer for the body is passed through the ViewContext, allowing things like HtmlHelpers
- // and ViewComponents to reference it.
- var oldWriter = context.Writer;
-
- try
- {
- context.Writer = bodyWriter;
- await ExecuteAsync();
-
- // Verify that RenderBody is called, or that RenderSection is called for all sections
- VerifyRenderedBodyOrSections();
- }
- finally
- {
- context.Writer = oldWriter;
- }
- }
-
- var bodyContent = contentBuilder.ToString();
- if (!string.IsNullOrEmpty(Layout))
- {
- await RenderLayoutAsync(context, bodyContent);
- }
- else
- {
- await context.Writer.WriteAsync(bodyContent);
- }
- }
-
- private async Task RenderLayoutAsync(ViewContext context, string bodyContent)
- {
- var virtualPathFactory = context.HttpContext.RequestServices.GetService();
- var layoutView = (RazorView)virtualPathFactory.CreateInstance(Layout);
-
- if (layoutView == null)
- {
- var message = Resources.FormatLayoutCannotBeLocated(Layout);
- throw new InvalidOperationException(message);
- }
-
- layoutView.PreviousSectionWriters = SectionWriters;
- layoutView.BodyContent = bodyContent;
- await layoutView.RenderAsync(context);
- }
+ public Dictionary SectionWriters { get; private set; }
public abstract Task ExecuteAsync();
@@ -326,6 +292,32 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
+ ///
+ /// Verifies that RenderBody is called and that RenderSection is called for all sections for a page that is
+ /// part of view execution hierarchy.
+ ///
+ public void EnsureBodyAndSectionsWereRendered()
+ {
+ // If PreviousSectionWriters is set, ensure all defined sections were rendered.
+ if (PreviousSectionWriters != null)
+ {
+ var sectionsNotRendered = PreviousSectionWriters.Keys.Except(_renderedSections,
+ StringComparer.OrdinalIgnoreCase);
+ if (sectionsNotRendered.Any())
+ {
+ var sectionNames = string.Join(", ", sectionsNotRendered);
+ throw new InvalidOperationException(Resources.FormatSectionsNotRendered(sectionNames));
+ }
+ }
+
+ // If BodyContent is set, ensure it was rendered.
+ if (BodyContent != null && !_renderedBody)
+ {
+ // If a body was defined, then RenderBody should have been called.
+ throw new InvalidOperationException(Resources.FormatRenderBodyNotCalled("RenderBody"));
+ }
+ }
+
private void EnsureMethodCanBeInvoked(string methodName)
{
if (PreviousSectionWriters == null)
@@ -333,24 +325,5 @@ namespace Microsoft.AspNet.Mvc.Razor
throw new InvalidOperationException(Resources.FormatView_MethodCannotBeCalled(methodName));
}
}
-
- private void VerifyRenderedBodyOrSections()
- {
- if (BodyContent != null)
- {
- var sectionsNotRendered = PreviousSectionWriters.Keys.Except(_renderedSections,
- StringComparer.OrdinalIgnoreCase);
- if (sectionsNotRendered.Any())
- {
- var sectionNames = String.Join(", ", sectionsNotRendered);
- throw new InvalidOperationException(Resources.FormatSectionsNotRendered(sectionNames));
- }
- else if (!_renderedBody)
- {
- // If a body was defined, then RenderBody should have been called.
- throw new InvalidOperationException(Resources.FormatRenderBodyNotCalled("RenderBody"));
- }
- }
- }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorViewActivator.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorPageActivator.cs
similarity index 79%
rename from src/Microsoft.AspNet.Mvc.Razor/RazorViewActivator.cs
rename to src/Microsoft.AspNet.Mvc.Razor/RazorPageActivator.cs
index 83752dc4f5..ffb424c3e6 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorViewActivator.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorPageActivator.cs
@@ -10,30 +10,26 @@ using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor
{
///
- public class RazorViewActivator : IRazorViewActivator
+ public class RazorPageActivator : IRazorPageActivator
{
- // Name of the "public TModel Model" property on RazorView
+ // Name of the "public TModel Model" property on RazorPage
private const string ModelPropertyName = "Model";
private readonly ITypeActivator _typeActivator;
- private readonly ConcurrentDictionary _activationInfo;
+ private readonly ConcurrentDictionary _activationInfo;
///
- /// Initializes a new instance of the RazorViewActivator class.
+ /// Initializes a new instance of the class.
///
- public RazorViewActivator(ITypeActivator typeActivator)
+ public RazorPageActivator(ITypeActivator typeActivator)
{
_typeActivator = typeActivator;
- _activationInfo = new ConcurrentDictionary();
+ _activationInfo = new ConcurrentDictionary();
}
- ///
- /// Activates the specified view by using the specified ViewContext.
- ///
- /// The view to activate.
- /// The ViewContext for the executing view.
- public void Activate([NotNull] RazorView view, [NotNull] ViewContext context)
+ ///
+ public void Activate([NotNull] RazorPage page, [NotNull] ViewContext context)
{
- var activationInfo = _activationInfo.GetOrAdd(view.GetType(),
+ var activationInfo = _activationInfo.GetOrAdd(page.GetType(),
CreateViewActivationInfo);
context.ViewData = CreateViewDataDictionary(context, activationInfo);
@@ -41,11 +37,11 @@ namespace Microsoft.AspNet.Mvc.Razor
for (var i = 0; i < activationInfo.PropertyActivators.Length; i++)
{
var activateInfo = activationInfo.PropertyActivators[i];
- activateInfo.Activate(view, context);
+ activateInfo.Activate(page, context);
}
}
- private ViewDataDictionary CreateViewDataDictionary(ViewContext context, ViewActivationInfo activationInfo)
+ private ViewDataDictionary CreateViewDataDictionary(ViewContext context, PageActivationInfo activationInfo)
{
// Create a ViewDataDictionary if the ViewContext.ViewData is not set or the type of
// ViewContext.ViewData is an incompatibile type.
@@ -66,10 +62,10 @@ namespace Microsoft.AspNet.Mvc.Razor
return context.ViewData;
}
- private ViewActivationInfo CreateViewActivationInfo(Type type)
+ private PageActivationInfo CreateViewActivationInfo(Type type)
{
// Look for a property named "Model". If it is non-null, we'll assume this is
- // the equivalent of TModel Model property on RazorView
+ // the equivalent of TModel Model property on RazorPage
var modelProperty = type.GetRuntimeProperty(ModelPropertyName);
if (modelProperty == null)
{
@@ -80,7 +76,7 @@ namespace Microsoft.AspNet.Mvc.Razor
var modelType = modelProperty.PropertyType;
var viewDataType = typeof(ViewDataDictionary<>).MakeGenericType(modelType);
- return new ViewActivationInfo
+ return new PageActivationInfo
{
ViewDataDictionaryType = viewDataType,
PropertyActivators = PropertyActivator.GetPropertiesToActivate(type,
@@ -115,7 +111,7 @@ namespace Microsoft.AspNet.Mvc.Razor
return new PropertyActivator(property, valueAccessor);
}
- private class ViewActivationInfo
+ private class PageActivationInfo
{
public PropertyActivator[] PropertyActivators { get; set; }
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorViewOfT.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorPageOfT.cs
similarity index 53%
rename from src/Microsoft.AspNet.Mvc.Razor/RazorViewOfT.cs
rename to src/Microsoft.AspNet.Mvc.Razor/RazorPageOfT.cs
index 0523215dc5..f895cb794c 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorViewOfT.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorPageOfT.cs
@@ -1,12 +1,13 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System.Threading.Tasks;
-using Microsoft.Framework.DependencyInjection;
-
namespace Microsoft.AspNet.Mvc.Razor
{
- public abstract class RazorView : RazorView
+ ///
+ /// Represents the properties and methods that are needed in order to render a view that uses Razor syntax.
+ ///
+ /// The type of the view data model.
+ public abstract class RazorPage : RazorPage
{
public TModel Model
{
@@ -18,13 +19,5 @@ namespace Microsoft.AspNet.Mvc.Razor
[Activate]
public ViewDataDictionary ViewData { get; set; }
-
- public override Task RenderAsync([NotNull] ViewContext context)
- {
- var viewActivator = context.HttpContext.RequestServices.GetService();
- viewActivator.Activate(this, context);
-
- return base.RenderAsync(context);
- }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs
similarity index 74%
rename from src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs
rename to src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs
index 42f1ca483d..081be65b5c 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorViewEngine.cs
@@ -26,11 +26,14 @@ namespace Microsoft.AspNet.Mvc.Razor
"/Views/Shared/{0}" + ViewExtension,
};
- private readonly IVirtualPathViewFactory _virtualPathFactory;
+ private readonly IRazorPageFactory _pageFactory;
+ private readonly IRazorPageActivator _viewActivator;
- public RazorViewEngine(IVirtualPathViewFactory virtualPathFactory)
+ public RazorViewEngine(IRazorPageFactory pageFactory,
+ IRazorPageActivator viewActivator)
{
- _virtualPathFactory = virtualPathFactory;
+ _pageFactory = pageFactory;
+ _viewActivator = viewActivator;
}
public IEnumerable ViewLocationFormats
@@ -41,18 +44,19 @@ namespace Microsoft.AspNet.Mvc.Razor
public ViewEngineResult FindView([NotNull] IDictionary context,
[NotNull] string viewName)
{
- var viewEngineResult = CreateViewEngineResult(context, viewName);
+ var viewEngineResult = CreateViewEngineResult(context, viewName, partial: false);
return viewEngineResult;
}
public ViewEngineResult FindPartialView([NotNull] IDictionary context,
[NotNull] string partialViewName)
{
- return FindView(context, partialViewName);
+ return CreateViewEngineResult(context, partialViewName, partial: true);
}
private ViewEngineResult CreateViewEngineResult([NotNull] IDictionary context,
- [NotNull] string viewName)
+ [NotNull] string viewName,
+ bool partial)
{
var nameRepresentsPath = IsSpecificPath(viewName);
@@ -64,8 +68,9 @@ namespace Microsoft.AspNet.Mvc.Razor
Resources.FormatViewMustEndInExtension(viewName, ViewExtension));
}
- var view = _virtualPathFactory.CreateInstance(viewName);
- return view != null ? ViewEngineResult.Found(viewName, view) :
+ var page = _pageFactory.CreateInstance(viewName);
+
+ return page != null ? CreateFoundResult(page, viewName, partial) :
ViewEngineResult.NotFound(viewName, new[] { viewName });
}
else
@@ -76,10 +81,10 @@ namespace Microsoft.AspNet.Mvc.Razor
foreach (var path in potentialPaths)
{
- var view = _virtualPathFactory.CreateInstance(path);
- if (view != null)
+ var page = _pageFactory.CreateInstance(path);
+ if (page != null)
{
- return ViewEngineResult.Found(viewName, view);
+ return CreateFoundResult(page, path, partial);
}
}
@@ -87,6 +92,15 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
+ private ViewEngineResult CreateFoundResult(RazorPage page, string viewName, bool partial)
+ {
+ var view = new RazorView(_pageFactory,
+ _viewActivator,
+ page,
+ executeViewHierarchy: !partial);
+ return ViewEngineResult.Found(viewName, view);
+ }
+
private static bool IsSpecificPath(string name)
{
return name[0] == '~' || name[0] == '/';
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx
index 208fa3dbcd..767a9ac8df 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx
@@ -153,6 +153,9 @@
View of type '{0}' cannot be activated by '{1}'.
+
+ '{0} must be set to access '{1}'.
+
View '{0}' must have extension '{1}' when the view represents a full path.
diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualPathViewFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualPathViewFactory.cs
deleted file mode 100644
index 293347dbab..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/IVirtualPathViewFactory.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using Microsoft.AspNet.Mvc.Rendering;
-
-namespace Microsoft.AspNet.Mvc.Razor
-{
- public interface IVirtualPathViewFactory
- {
- IView CreateInstance(string virtualPath);
- }
-}
diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs
index 9e9a02e729..f4927cc027 100644
--- a/src/Microsoft.AspNet.Mvc/MvcServices.cs
+++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs
@@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Transient();
yield return describe.Transient();
- yield return describe.Instance(new MvcRazorHost(typeof(RazorView).FullName));
+ yield return describe.Instance(new MvcRazorHost(typeof(RazorPage).FullName));
yield return describe.Transient();
@@ -44,9 +44,9 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Scoped();
yield return describe.Singleton();
- yield return describe.Singleton();
+ yield return describe.Singleton();
// Virtual path view factory needs to stay scoped so views can get get scoped services.
- yield return describe.Scoped();
+ yield return describe.Scoped();
yield return describe.Singleton();
yield return describe.Transient,
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj b/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj
index 76668c07e9..9ff61cc4c7 100644
--- a/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/Microsoft.AspNet.Mvc.FunctionalTests.kproj
@@ -30,6 +30,7 @@
+
diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/ViewEngineTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/ViewEngineTests.cs
new file mode 100644
index 0000000000..266ac264c2
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/ViewEngineTests.cs
@@ -0,0 +1,89 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.TestHost;
+using RazorWebSite;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.FunctionalTests
+{
+ public class ViewEngineTests
+ {
+ private readonly IServiceProvider _provider = TestHelper.CreateServices("RazorWebSite");
+ private readonly Action _app = new Startup().Configure;
+
+ public static IEnumerable