Rearrange ViewContext

This commit is contained in:
Ryan Nowak 2014-04-09 11:54:58 -07:00
parent cda73e95a8
commit 408d4056b1
17 changed files with 96 additions and 68 deletions

View File

@ -60,5 +60,8 @@
<Compile Include="Startup.cs" /> <Compile Include="Startup.cs" />
<Compile Include="ViewMetadata.cs" /> <Compile Include="ViewMetadata.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -23,5 +23,8 @@
<Compile Include="NotNullArgument.cs" /> <Compile Include="NotNullArgument.cs" />
<Compile Include="TypeExtensions.cs" /> <Compile Include="TypeExtensions.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -7,6 +7,12 @@ namespace Microsoft.AspNet.Mvc
{ {
public class ActionContext public class ActionContext
{ {
public ActionContext([NotNull] ActionContext actionContext)
: this(actionContext.HttpContext, actionContext.Router, actionContext.RouteValues, actionContext.ActionDescriptor)
{
ModelState = actionContext.ModelState;
}
public ActionContext(HttpContext httpContext, IRouter router, IDictionary<string, object> routeValues, ActionDescriptor actionDescriptor) public ActionContext(HttpContext httpContext, IRouter router, IDictionary<string, object> routeValues, ActionDescriptor actionDescriptor)
{ {
HttpContext = httpContext; HttpContext = httpContext;

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Mvc
context.HttpContext.Response.ContentType = "text/html"; context.HttpContext.Response.ContentType = "text/html";
using (var writer = new StreamWriter(context.HttpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true)) using (var writer = new StreamWriter(context.HttpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
{ {
var viewContext = CreateViewContext(context, writer); var viewContext = new ViewContext(context, view, ViewData, writer);
await view.RenderAsync(viewContext); await view.RenderAsync(viewContext);
} }
} }
@ -44,18 +44,5 @@ namespace Microsoft.AspNet.Mvc
var result = _viewEngine.FindView(context, viewName); var result = _viewEngine.FindView(context, viewName);
return result.View; return result.View;
} }
private ViewContext CreateViewContext([NotNull] ActionContext actionContext, [NotNull] TextWriter writer)
{
var urlHelper = _serviceProvider.GetService<IUrlHelper>();
var viewContext = new ViewContext(_serviceProvider, actionContext.HttpContext, actionContext.RouteValues)
{
ViewData = ViewData,
Writer = writer,
};
return viewContext;
}
} }
} }

View File

@ -281,15 +281,16 @@ namespace Microsoft.AspNet.Mvc.Rendering
var newViewData = new ViewDataDictionary(baseViewData, model); var newViewData = new ViewDataDictionary(baseViewData, model);
var newViewContext = new ViewContext(ViewContext)
var viewEngineResult = _viewEngine.FindPartialView(ViewContext.RouteValues, partialViewName);
var view = viewEngineResult.View;
using (view as IDisposable)
{ {
ViewData = newViewData, var viewContext = new ViewContext(ViewContext, view, newViewData, writer);
Writer = writer await viewEngineResult.View.RenderAsync(viewContext);
}; }
var viewEngineResult = _viewEngine.FindPartialView(newViewContext.ViewEngineContext, partialViewName);
await viewEngineResult.View.RenderAsync(newViewContext);
} }
public HtmlString Password(string name, object value, object htmlAttributes) public HtmlString Password(string name, object value, object htmlAttributes)

View File

@ -44,20 +44,20 @@ namespace Microsoft.AspNet.Mvc.Rendering
var fullViewName = modeViewPath + "/" + viewName; var fullViewName = modeViewPath + "/" + viewName;
// Forcing synchronous behavior so users don't have to await templates. // Forcing synchronous behavior so users don't have to await templates.
var viewEngineResult = _viewEngine.FindPartialView(_viewContext.ViewEngineContext, fullViewName); var viewEngineResult = _viewEngine.FindPartialView(_viewContext.RouteValues, fullViewName);
if (viewEngineResult.Success) if (viewEngineResult.Success)
{ {
using (var writer = new StringWriter(CultureInfo.InvariantCulture)) using (var writer = new StringWriter(CultureInfo.InvariantCulture))
{ {
// Forcing synchronous behavior so users don't have to await templates. // Forcing synchronous behavior so users don't have to await templates.
// TODO: Pass through TempData once implemented. // TODO: Pass through TempData once implemented.
viewEngineResult.View.RenderAsync(new ViewContext(_viewContext) var view = viewEngineResult.View;
using (view as IDisposable)
{ {
ViewData = _viewData, var viewContext = new ViewContext(_viewContext, viewEngineResult.View, _viewData, writer);
Writer = writer, viewEngineResult.View.RenderAsync(viewContext).Wait();
}).Wait(); return writer.ToString();
}
return writer.ToString();
} }
} }

View File

@ -31,15 +31,6 @@ namespace Microsoft.AspNet.Mvc
public async Task ExecuteAsync([NotNull] ViewComponentContext context) public async Task ExecuteAsync([NotNull] ViewComponentContext context)
{ {
var childViewContext = new ViewContext(
context.ViewContext.ServiceProvider,
context.ViewContext.HttpContext,
context.ViewContext.ViewEngineContext)
{
ViewData = _viewData ?? context.ViewContext.ViewData,
Writer = context.Writer,
};
string qualifiedViewName; string qualifiedViewName;
if (_viewName.Length > 0 && _viewName[0] == '/') if (_viewName.Length > 0 && _viewName[0] == '/')
{ {
@ -66,7 +57,14 @@ namespace Microsoft.AspNet.Mvc
_viewName); _viewName);
} }
var view = FindView(context.ViewContext.ViewEngineContext, qualifiedViewName); var view = FindView(context.ViewContext.RouteValues, qualifiedViewName);
var childViewContext = new ViewContext(
context.ViewContext,
view,
_viewData ?? context.ViewContext.ViewData,
context.Writer);
using (view as IDisposable) using (view as IDisposable)
{ {
await view.RenderAsync(childViewContext); await view.RenderAsync(childViewContext);

View File

@ -6,7 +6,7 @@ using Microsoft.AspNet.Mvc.Rendering;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public class ViewContext public class ViewContext : ActionContext
{ {
private DynamicViewData _viewBag; private DynamicViewData _viewBag;
@ -14,25 +14,39 @@ namespace Microsoft.AspNet.Mvc
private readonly FormContext _defaultFormContext = new FormContext(); private readonly FormContext _defaultFormContext = new FormContext();
private FormContext _formContext; private FormContext _formContext;
public ViewContext([NotNull] ViewContext viewContext)
: this(viewContext.ServiceProvider, viewContext.HttpContext, viewContext.ViewEngineContext)
{
UnobtrusiveJavaScriptEnabled = viewContext.UnobtrusiveJavaScriptEnabled;
ClientValidationEnabled = viewContext.ClientValidationEnabled;
}
public ViewContext(IServiceProvider serviceProvider, HttpContext httpContext, public ViewContext(
IDictionary<string, object> viewEngineContext) [NotNull] ActionContext actionContext,
[NotNull] IView view,
[NotNull] ViewDataDictionary viewData,
[NotNull] TextWriter writer)
: base(actionContext)
{ {
ServiceProvider = serviceProvider; View = view;
HttpContext = httpContext; ViewData = viewData;
ViewEngineContext = viewEngineContext; Writer = writer;
_formContext = _defaultFormContext; _formContext = _defaultFormContext;
UnobtrusiveJavaScriptEnabled = true; UnobtrusiveJavaScriptEnabled = true;
ClientValidationEnabled = true; ClientValidationEnabled = true;
} }
public ViewContext(
[NotNull] ViewContext viewContext,
[NotNull] IView view,
[NotNull] ViewDataDictionary viewData,
[NotNull] TextWriter writer)
: base(viewContext)
{
_formContext = viewContext.FormContext;
UnobtrusiveJavaScriptEnabled = viewContext.UnobtrusiveJavaScriptEnabled;
ClientValidationEnabled = viewContext.ClientValidationEnabled;
View = view;
ViewData = viewData;
Writer = writer;
}
public virtual FormContext FormContext public virtual FormContext FormContext
{ {
get get
@ -46,10 +60,6 @@ namespace Microsoft.AspNet.Mvc
} }
} }
public HttpContext HttpContext { get; private set; }
public IServiceProvider ServiceProvider { get; private set; }
public bool UnobtrusiveJavaScriptEnabled { get; set; } public bool UnobtrusiveJavaScriptEnabled { get; set; }
public bool ClientValidationEnabled { get; set; } public bool ClientValidationEnabled { get; set; }
@ -67,9 +77,9 @@ namespace Microsoft.AspNet.Mvc
} }
} }
public ViewDataDictionary ViewData { get; set; } public IView View { get; set; }
public IDictionary<string, object> ViewEngineContext { get; private set; } public ViewDataDictionary ViewData { get; set; }
public TextWriter Writer { get; set; } public TextWriter Writer { get; set; }
} }

View File

@ -86,9 +86,9 @@ namespace Microsoft.AspNet.Mvc.Razor
{ {
Contract.Assert(Context != null); Contract.Assert(Context != null);
Url = Context.ServiceProvider.GetService<IUrlHelper>(); Url = Context.HttpContext.RequestServices.GetService<IUrlHelper>();
Component = Context.ServiceProvider.GetService<IViewComponentHelper>(); Component = Context.HttpContext.RequestServices.GetService<IViewComponentHelper>();
var contextable = Component as ICanHasViewContext; var contextable = Component as ICanHasViewContext;
if (contextable != null) if (contextable != null)
@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Mvc.Razor
private async Task RenderLayoutAsync(ViewContext context, string bodyContent) private async Task RenderLayoutAsync(ViewContext context, string bodyContent)
{ {
var virtualPathFactory = context.ServiceProvider.GetService<IVirtualPathViewFactory>(); var virtualPathFactory = context.HttpContext.RequestServices.GetService<IVirtualPathViewFactory>();
var layoutView = (RazorView)virtualPathFactory.CreateInstance(Layout); var layoutView = (RazorView)virtualPathFactory.CreateInstance(Layout);
if (layoutView == null) if (layoutView == null)

View File

@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc.Razor
} }
else else
{ {
var metadataProvider = context.ServiceProvider.GetService<IModelMetadataProvider>(); var metadataProvider = context.HttpContext.RequestServices.GetService<IModelMetadataProvider>();
ViewData = new ViewDataDictionary<TModel>(metadataProvider); ViewData = new ViewDataDictionary<TModel>(metadataProvider);
} }
@ -46,7 +46,7 @@ namespace Microsoft.AspNet.Mvc.Razor
private void InitHelpers(ViewContext context) private void InitHelpers(ViewContext context)
{ {
Html = context.ServiceProvider.GetService<IHtmlHelper<TModel>>(); Html = context.HttpContext.RequestServices.GetService<IHtmlHelper<TModel>>();
var contextable = Html as ICanHasViewContext; var contextable = Html as ICanHasViewContext;
if (contextable != null) if (contextable != null)

View File

@ -22,5 +22,8 @@
<ItemGroup> <ItemGroup>
<Compile Include="MvcServices.cs" /> <Compile Include="MvcServices.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -36,5 +36,8 @@
<Compile Include="TypeHelperTest.cs" /> <Compile Include="TypeHelperTest.cs" />
<Compile Include="UrlHelperTest.cs" /> <Compile Include="UrlHelperTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
public void SettingViewData_AlsoUpdatesViewBag() public void SettingViewData_AlsoUpdatesViewBag()
{ {
// Arrange (eventually passing null to these consturctors will throw) // Arrange (eventually passing null to these consturctors will throw)
var context = new ViewContext(serviceProvider: null, httpContext: null, viewEngineContext: null); var context = new ViewContext(new ActionContext(null, null, null, null), view: null, viewData: null, writer: null);
var originalViewData = context.ViewData = new ViewDataDictionary(metadataProvider: null); var originalViewData = context.ViewData = new ViewDataDictionary(metadataProvider: null);
var replacementViewData = new ViewDataDictionary(metadataProvider: null); var replacementViewData = new ViewDataDictionary(metadataProvider: null);

View File

@ -50,5 +50,8 @@
<Compile Include="ValueProviders\ReadableStringCollectionValueProviderTests.cs" /> <Compile Include="ValueProviders\ReadableStringCollectionValueProviderTests.cs" />
<Compile Include="ValueProviders\ValueProviderResultTest.cs" /> <Compile Include="ValueProviders\ValueProviderResultTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -26,5 +26,8 @@
<Compile Include="RazorViewTest.cs" /> <Compile Include="RazorViewTest.cs" />
<Compile Include="SpanFactory.cs" /> <Compile Include="SpanFactory.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View File

@ -1,6 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Testing; using Microsoft.AspNet.Testing;
using Moq; using Moq;
@ -295,10 +296,16 @@ Layout end
var serviceProvider = new Mock<IServiceProvider>(); var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(f => f.GetService(typeof(IVirtualPathViewFactory))) serviceProvider.Setup(f => f.GetService(typeof(IVirtualPathViewFactory)))
.Returns(viewFactory.Object); .Returns(viewFactory.Object);
return new ViewContext(serviceProvider.Object, httpContext: null, viewEngineContext: null)
{ var httpContext = new Mock<HttpContext>();
Writer = new StringWriter() httpContext.SetupGet(c => c.RequestServices).Returns(serviceProvider.Object);
};
var actionContext = new ActionContext(httpContext.Object, null, null, null);
return new ViewContext(
actionContext,
layoutView,
null,
new StringWriter());
} }
public abstract class TestableRazorView : RazorView public abstract class TestableRazorView : RazorView

View File

@ -4,6 +4,7 @@
"Microsoft.AspNet.Abstractions": "0.1-alpha-*", "Microsoft.AspNet.Abstractions": "0.1-alpha-*",
"Microsoft.AspNet.FileSystems": "0.1-alpha-*", "Microsoft.AspNet.FileSystems": "0.1-alpha-*",
"Microsoft.AspNet.Razor": "0.1-alpha-*", "Microsoft.AspNet.Razor": "0.1-alpha-*",
"Microsoft.AspNet.Routing": "0.1-alpha-*",
"Microsoft.AspNet.Mvc.Core" : "", "Microsoft.AspNet.Mvc.Core" : "",
"Microsoft.AspNet.Mvc.Razor" : "", "Microsoft.AspNet.Mvc.Razor" : "",
"Microsoft.AspNet.Testing" : "0.1-alpha-*", "Microsoft.AspNet.Testing" : "0.1-alpha-*",