diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs index 610a1d72c1..5039eaa883 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/ViewResult.cs @@ -8,29 +8,26 @@ using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.Rendering; +using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Mvc { public class ViewResult : ActionResult { private const int BufferSize = 1024; - private readonly IServiceProvider _serviceProvider; - private readonly IViewEngine _viewEngine; - - public ViewResult([NotNull] IServiceProvider serviceProvider, [NotNull] IViewEngine viewEngine) - { - _serviceProvider = serviceProvider; - _viewEngine = viewEngine; - } public string ViewName { get; set; } public ViewDataDictionary ViewData { get; set; } + public IViewEngine ViewEngine { get; set; } + public override async Task ExecuteResultAsync([NotNull] ActionContext context) { + var viewEngine = ViewEngine ?? context.HttpContext.RequestServices.GetService(); + var viewName = ViewName ?? context.ActionDescriptor.Name; - var view = FindView(context.RouteData.Values, viewName); + var view = FindView(viewEngine, context.RouteData.Values, viewName); using (view as IDisposable) { @@ -56,9 +53,12 @@ namespace Microsoft.AspNet.Mvc } } - private IView FindView([NotNull] IDictionary context, [NotNull] string viewName) + private static IView FindView( + [NotNull] IViewEngine viewEngine, + [NotNull] IDictionary context, + [NotNull] string viewName) { - var result = _viewEngine.FindView(context, viewName); + var result = viewEngine.FindView(context, viewName); if (!result.Success) { var locations = string.Empty; diff --git a/src/Microsoft.AspNet.Mvc.Core/Controller.cs b/src/Microsoft.AspNet.Mvc.Core/Controller.cs index 9e7b5e6d2b..2df59735a7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controller.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controller.cs @@ -35,12 +35,6 @@ namespace Microsoft.AspNet.Mvc [Activate] public ActionContext ActionContext { get; set; } - [Activate] - public IServiceProvider ServiceProvider { get; set; } - - [Activate] - public IViewEngine ViewEngine { get; set; } - [Activate] public IUrlHelper Url { get; set; } @@ -122,7 +116,7 @@ namespace Microsoft.AspNet.Mvc ViewData.Model = model; } - return new ViewResult(ServiceProvider, ViewEngine) + return new ViewResult() { ViewName = viewName, ViewData = ViewData, diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs index 09c4991692..2ea8491b8c 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs @@ -23,17 +23,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var expected = new byte[] { 97, 98, 99, 100 }; - var memoryStream = new MemoryStream(); - var response = new Mock(); - response.SetupGet(r => r.Body) - .Returns(memoryStream); - var context = new Mock(); - context.SetupGet(c => c.Response) - .Returns(response.Object); - var routeDictionary = new Dictionary(); - var actionContext = new ActionContext(context.Object, - new RouteData() { Values = routeDictionary }, - new ActionDescriptor()); + var view = new Mock(); view.Setup(v => v.RenderAsync(It.IsAny())) .Callback((ViewContext v) => @@ -41,11 +31,85 @@ namespace Microsoft.AspNet.Mvc.Core.Test v.Writer.Write("abcd"); }) .Returns(Task.FromResult(0)); - var serviceProvider = Mock.Of(); + + var routeDictionary = new Dictionary(); + var viewEngine = new Mock(); viewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); - var viewResult = new ViewResult(serviceProvider, viewEngine.Object); + + var serviceProvider = new Mock(); + serviceProvider.Setup(sp => sp.GetService(typeof(IViewEngine))).Returns(viewEngine.Object); + + var memoryStream = new MemoryStream(); + var response = new Mock(); + response.SetupGet(r => r.Body) + .Returns(memoryStream); + + var context = new Mock(); + context.SetupGet(c => c.Response) + .Returns(response.Object); + context.SetupGet(c => c.RequestServices) + .Returns(serviceProvider.Object); + + var actionContext = new ActionContext(context.Object, + new RouteData() { Values = routeDictionary }, + new ActionDescriptor()); + + + var viewResult = new ViewResult(); + + // Act + await viewResult.ExecuteResultAsync(actionContext); + + // Assert + Assert.Equal(expected, memoryStream.ToArray()); + } + + [Fact] + public async Task ExecuteResultAsync_UsesProvidedViewEngine() + { + // Arrange + var expected = new byte[] { 97, 98, 99, 100 }; + + var view = new Mock(); + view.Setup(v => v.RenderAsync(It.IsAny())) + .Callback((ViewContext v) => + { + v.Writer.Write("abcd"); + }) + .Returns(Task.FromResult(0)); + + var routeDictionary = new Dictionary(); + + var goodViewEngine = new Mock(); + goodViewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) + .Returns(ViewEngineResult.Found("MyView", view.Object)); + + var badViewEngine = new Mock(MockBehavior.Strict); + + var serviceProvider = new Mock(); + serviceProvider.Setup(sp => sp.GetService(typeof(IViewEngine))).Returns(badViewEngine.Object); + + var memoryStream = new MemoryStream(); + var response = new Mock(); + response.SetupGet(r => r.Body) + .Returns(memoryStream); + + var context = new Mock(); + context.SetupGet(c => c.Response) + .Returns(response.Object); + context.SetupGet(c => c.RequestServices) + .Returns(serviceProvider.Object); + + var actionContext = new ActionContext(context.Object, + new RouteData() { Values = routeDictionary }, + new ActionDescriptor()); + + var viewResult = new ViewResult() + { + ViewEngine = goodViewEngine.Object, + }; // Act await viewResult.ExecuteResultAsync(actionContext); @@ -63,17 +127,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var longString = new string('a', writtenLength); - var memoryStream = new MemoryStream(); - var response = new Mock(); - response.SetupGet(r => r.Body) - .Returns(memoryStream); - var context = new Mock(); - context.SetupGet(c => c.Response) - .Returns(response.Object); + var routeDictionary = new Dictionary(); - var actionContext = new ActionContext(context.Object, - new RouteData() { Values = routeDictionary }, - new ActionDescriptor()); + var view = new Mock(); view.Setup(v => v.RenderAsync(It.IsAny())) .Callback((ViewContext v) => @@ -81,11 +137,28 @@ namespace Microsoft.AspNet.Mvc.Core.Test v.Writer.Write(longString); throw new Exception(); }); - var serviceProvider = Mock.Of(); + var viewEngine = new Mock(); viewEngine.Setup(v => v.FindView(routeDictionary, It.IsAny())) .Returns(ViewEngineResult.Found("MyView", view.Object)); - var viewResult = new ViewResult(serviceProvider, viewEngine.Object); + + var serviceProvider = new Mock(); + serviceProvider.Setup(sp => sp.GetService(typeof(IViewEngine))).Returns(viewEngine.Object); + + var memoryStream = new MemoryStream(); + var response = new Mock(); + response.SetupGet(r => r.Body) + .Returns(memoryStream); + var context = new Mock(); + context.SetupGet(c => c.Response) + .Returns(response.Object); + context.SetupGet(c => c.RequestServices).Returns(serviceProvider.Object); + + var actionContext = new ActionContext(context.Object, + new RouteData() { Values = routeDictionary }, + new ActionDescriptor()); + + var viewResult = new ViewResult(); // Act await Record.ExceptionAsync(() => viewResult.ExecuteResultAsync(actionContext));