diff --git a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHostOptions.cs b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHostOptions.cs index 3ab5f0359c..3e9b26e68d 100644 --- a/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHostOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Razor.Host/MvcRazorHostOptions.cs @@ -16,7 +16,8 @@ namespace Microsoft.AspNet.Mvc.Razor ActivateAttributeName = "Microsoft.AspNet.Mvc.ActivateAttribute"; DefaultInjectedProperties = new List() { - new InjectDescriptor("Microsoft.AspNet.Mvc.Rendering.IHtmlHelper", "Html") + new InjectDescriptor("Microsoft.AspNet.Mvc.Rendering.IHtmlHelper", "Html"), + new InjectDescriptor("Microsoft.AspNet.Mvc.IViewComponentHelper", "Component"), }; } diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs index d00497374c..2615dae58f 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.Contracts; using System.IO; using System.Linq; using System.Net; @@ -21,7 +20,8 @@ namespace Microsoft.AspNet.Mvc.Razor private readonly HashSet _renderedSections = new HashSet(StringComparer.OrdinalIgnoreCase); private bool _renderedBody; - public IViewComponentHelper Component { get; private set; } + [Activate] + public IUrlHelper Url { get; set; } public HttpContext Context { @@ -42,8 +42,6 @@ namespace Microsoft.AspNet.Mvc.Razor protected TextWriter Output { get; set; } - public IUrlHelper Url { get; private set; } - public virtual IPrincipal User { get @@ -76,8 +74,6 @@ namespace Microsoft.AspNet.Mvc.Razor SectionWriters = new Dictionary(StringComparer.OrdinalIgnoreCase); ViewContext = context; - InitHelpers(); - var contentBuilder = new StringBuilder(1024); using (var bodyWriter = new StringWriter(contentBuilder)) { @@ -112,22 +108,6 @@ namespace Microsoft.AspNet.Mvc.Razor } } - private void InitHelpers() - { - Contract.Assert(ViewContext != null); - Contract.Assert(Context != null); - - Url = Context.RequestServices.GetService(); - - Component = Context.RequestServices.GetService(); - - var contextable = Component as ICanHasViewContext; - if (contextable != null) - { - contextable.Contextualize(ViewContext); - } - } - private async Task RenderLayoutAsync(ViewContext context, string bodyContent) { var virtualPathFactory = context.HttpContext.RequestServices.GetService(); diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/ActivatorTests.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/ActivatorTests.cs index d8f548d633..20505e8314 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/ActivatorTests.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/ActivatorTests.cs @@ -61,5 +61,52 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var body = await result.HttpContext.Response.ReadBodyAsStringAsync(); Assert.Equal(expected, body); } + + [Fact] + public async Task ViewActivator_ActivatesDefaultInjectedProperties() + { + var server = TestServer.Create(_provider, _app); + var client = server.Handler; + var expected = " world!"; + + // Act + var result = await client.GetAsync("http://localhost/View/ConsumeDefaultProperties"); + + // Assert + var body = await result.HttpContext.Response.ReadBodyAsStringAsync(); + Assert.Equal(expected, body.Trim()); + } + + [Fact] + public async Task ViewActivator_ActivatesAndContextualizesInjectedServices() + { + var server = TestServer.Create(_provider, _app); + var client = server.Handler; + var expected = "4 test-value"; + + // Act + var result = await client.GetAsync("http://localhost/View/ConsumeInjectedService?test=test-value"); + + // Assert + var body = await result.HttpContext.Response.ReadBodyAsStringAsync(); + Assert.Equal(expected, body.Trim()); + } + + [Fact] + public async Task ViewActivator_ActivatesServicesFromBaseType() + { + var server = TestServer.Create(_provider, _app); + var client = server.Handler; + var expected = +@"/content/scripts/test.js +/View/ConsumeDefaultProperties"; + + // Act + var result = await client.GetAsync("http://localhost/View/ConsumeServicesFromBaseType"); + + // Assert + var body = await result.HttpContext.Response.ReadBodyAsStringAsync(); + Assert.Equal(expected, body.Trim()); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Inject.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Inject.cs index aae5630d99..297e8e9565 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Inject.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Inject.cs @@ -31,6 +31,8 @@ using MyNamespace { get; private set; } [Microsoft.AspNet.Mvc.ActivateAttribute] public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNet.Mvc.ActivateAttribute] + public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } #line hidden diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/InjectWithModel.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/InjectWithModel.cs index e1dc486e03..f01a3aefb6 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/InjectWithModel.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/InjectWithModel.cs @@ -37,6 +37,8 @@ #line default #line hidden { get; private set; } + [Microsoft.AspNet.Mvc.ActivateAttribute] + public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } #line hidden diff --git a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Model.cs b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Model.cs index 71dde59fe9..e5e11623f7 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Model.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Host.Test/TestFiles/Output/Model.cs @@ -23,6 +23,8 @@ #line hidden [Microsoft.AspNet.Mvc.ActivateAttribute] public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper Html { get; private set; } + [Microsoft.AspNet.Mvc.ActivateAttribute] + public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; } #line hidden diff --git a/test/WebSites/ActivatorWebSite/ActivatorWebSite.kproj b/test/WebSites/ActivatorWebSite/ActivatorWebSite.kproj index fe131b4912..1c50011d2e 100644 --- a/test/WebSites/ActivatorWebSite/ActivatorWebSite.kproj +++ b/test/WebSites/ActivatorWebSite/ActivatorWebSite.kproj @@ -24,12 +24,18 @@ + + + + + + diff --git a/test/WebSites/ActivatorWebSite/Components/TestComponent.cs b/test/WebSites/ActivatorWebSite/Components/TestComponent.cs new file mode 100644 index 0000000000..df1a742d50 --- /dev/null +++ b/test/WebSites/ActivatorWebSite/Components/TestComponent.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNet.Mvc; + +namespace ActivatorWebSite +{ + [ViewComponent(Name = "Test")] + public class TestComponent : ViewComponent + { + public IViewComponentResult Invoke(string content) + { + return Content(content + "!"); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ActivatorWebSite/Controllers/ViewController.cs b/test/WebSites/ActivatorWebSite/Controllers/ViewController.cs new file mode 100644 index 0000000000..2dfbdefa68 --- /dev/null +++ b/test/WebSites/ActivatorWebSite/Controllers/ViewController.cs @@ -0,0 +1,28 @@ +// 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; + +namespace ActivatorWebSite +{ + /// + /// Controller that verifies if view activation works. + /// + public class ViewController : Controller + { + public ViewResult ConsumeDefaultProperties() + { + return View(); + } + + public ViewResult ConsumeInjectedService() + { + return View(); + } + + public ViewResult ConsumeServicesFromBaseType() + { + return View(); + } + } +} \ No newline at end of file diff --git a/test/WebSites/ActivatorWebSite/Services/MyService.cs b/test/WebSites/ActivatorWebSite/Services/MyService.cs index 04ac32b57a..3be699bcf6 100644 --- a/test/WebSites/ActivatorWebSite/Services/MyService.cs +++ b/test/WebSites/ActivatorWebSite/Services/MyService.cs @@ -1,8 +1,6 @@ // 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; - namespace ActivatorWebSite { public class MyService diff --git a/test/WebSites/ActivatorWebSite/Services/ViewService.cs b/test/WebSites/ActivatorWebSite/Services/ViewService.cs new file mode 100644 index 0000000000..a4eec502bd --- /dev/null +++ b/test/WebSites/ActivatorWebSite/Services/ViewService.cs @@ -0,0 +1,26 @@ +// 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; +using Microsoft.AspNet.Mvc.Rendering; + +namespace ActivatorWebSite +{ + /// + /// A service that needs to be contextualized. + /// + public class ViewService : ICanHasViewContext + { + private ViewContext _context; + + public void Contextualize(ViewContext viewContext) + { + _context = viewContext; + } + + public string GetValue() + { + return _context.HttpContext.Request.Query["test"]; + } + } +} \ No newline at end of file diff --git a/test/WebSites/ActivatorWebSite/Startup.cs b/test/WebSites/ActivatorWebSite/Startup.cs index 61605409af..388428623c 100644 --- a/test/WebSites/ActivatorWebSite/Startup.cs +++ b/test/WebSites/ActivatorWebSite/Startup.cs @@ -19,6 +19,7 @@ namespace ActivatorWebSite // Add MVC services to the services container services.AddMvc(configuration); services.AddInstance(new MyService()); + services.AddScoped(); }); // Add MVC to the request pipeline diff --git a/test/WebSites/ActivatorWebSite/Views/View/ConsumeDefaultProperties.cshtml b/test/WebSites/ActivatorWebSite/Views/View/ConsumeDefaultProperties.cshtml new file mode 100644 index 0000000000..c7a5a66e68 --- /dev/null +++ b/test/WebSites/ActivatorWebSite/Views/View/ConsumeDefaultProperties.cshtml @@ -0,0 +1 @@ +@Html.Label("Hello") @Component.Invoke("Test", "world") \ No newline at end of file diff --git a/test/WebSites/ActivatorWebSite/Views/View/ConsumeInjectedService.cshtml b/test/WebSites/ActivatorWebSite/Views/View/ConsumeInjectedService.cshtml new file mode 100644 index 0000000000..3247c972c6 --- /dev/null +++ b/test/WebSites/ActivatorWebSite/Views/View/ConsumeInjectedService.cshtml @@ -0,0 +1,5 @@ +@using ActivatorWebSite +@inject MyService MyServiceInstance +@inject ViewService ViewServiceInstance + +@MyServiceInstance.Random @ViewServiceInstance.GetValue() \ No newline at end of file diff --git a/test/WebSites/ActivatorWebSite/Views/View/ConsumeServicesFromBaseType.cshtml b/test/WebSites/ActivatorWebSite/Views/View/ConsumeServicesFromBaseType.cshtml new file mode 100644 index 0000000000..7a8298dacc --- /dev/null +++ b/test/WebSites/ActivatorWebSite/Views/View/ConsumeServicesFromBaseType.cshtml @@ -0,0 +1,2 @@ +@Href("~/content/scripts/test.js") +@Url.Action("ConsumeDefaultProperties") \ No newline at end of file