Make RazorPage.IUrlHelper a non-public property

* This allows for injection of the property in cshtml files wthout running
in to compilation errors
* Make IUrlHelper a default injected service

Fixes #816
This commit is contained in:
Pranav K 2014-08-06 16:32:07 -07:00
parent 6ee034e64f
commit 9e68a163fd
9 changed files with 47 additions and 11 deletions

View File

@ -18,6 +18,7 @@ namespace Microsoft.AspNet.Mvc.Razor
{
new InjectDescriptor("Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<TModel>", "Html"),
new InjectDescriptor("Microsoft.AspNet.Mvc.IViewComponentHelper", "Component"),
new InjectDescriptor("Microsoft.AspNet.Mvc.IUrlHelper", "Url"),
};
}

View File

@ -10,6 +10,7 @@ using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.Framework.DependencyInjection;
namespace Microsoft.AspNet.Mvc.Razor
{
@ -18,6 +19,7 @@ namespace Microsoft.AspNet.Mvc.Razor
/// </summary>
public abstract class RazorPage : IRazorPage
{
private IUrlHelper _urlHelper;
private readonly HashSet<string> _renderedSections = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private bool _renderedBody;
@ -26,9 +28,6 @@ namespace Microsoft.AspNet.Mvc.Razor
SectionWriters = new Dictionary<string, HelperResult>(StringComparer.OrdinalIgnoreCase);
}
[Activate]
public IUrlHelper Url { get; set; }
public HttpContext Context
{
get
@ -231,7 +230,12 @@ namespace Microsoft.AspNet.Mvc.Razor
public virtual string Href([NotNull] string contentPath)
{
return Url.Content(contentPath);
if (_urlHelper == null)
{
_urlHelper = Context.RequestServices.GetService<IUrlHelper>();
}
return _urlHelper.Content(contentPath);
}
private void WritePositionTaggedLiteral(TextWriter writer, string value, int position)

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
{
var server = TestServer.Create(_provider, _app);
var client = server.Handler;
var expected = "<label for=\"Hello\">Hello</label> world!";
var expected = @"<label for=""Hello"">Hello</label> world! /View/ConsumeServicesFromBaseType";
// Act
var result = await client.GetAsync("http://localhost/View/ConsumeDefaultProperties");
@ -97,9 +97,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
{
var server = TestServer.Create(_provider, _app);
var client = server.Handler;
var expected =
@"/content/scripts/test.js
/View/ConsumeDefaultProperties";
var expected =
@"/content/scripts/test.js";
// Act
var result = await client.GetAsync("http://localhost/View/ConsumeServicesFromBaseType");

View File

@ -33,6 +33,8 @@ using MyNamespace
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
#line hidden

View File

@ -39,6 +39,8 @@
{ get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
#line hidden

View File

@ -25,6 +25,8 @@
public Microsoft.AspNet.Mvc.Rendering.IHtmlHelper<System.Collections.IEnumerable> Html { get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
public Microsoft.AspNet.Mvc.IViewComponentHelper Component { get; private set; }
[Microsoft.AspNet.Mvc.ActivateAttribute]
public Microsoft.AspNet.Mvc.IUrlHelper Url { get; private set; }
#line hidden

View File

@ -155,7 +155,6 @@ namespace Microsoft.AspNet.Mvc.Razor
Assert.Equal(true, actual);
}
[Fact]
public async Task RenderSection_ThrowsIfSectionIsRenderedMoreThanOnce()
{
@ -265,6 +264,34 @@ Layout end
Assert.Equal(expected, actual);
}
[Fact]
public async Task Href_ReadsUrlHelperFromServiceCollection()
{
// Arrange
var expected = "urlhelper-url";
var helper = new Mock<IUrlHelper>();
helper.Setup(h => h.Content("url"))
.Returns(expected)
.Verifiable();
var page = CreatePage(v =>
{
v.Write(v.Href("url"));
});
var services = new Mock<IServiceProvider>();
services.Setup(s => s.GetService(typeof(IUrlHelper)))
.Returns(helper.Object);
Mock.Get(page.Context).Setup(c => c.RequestServices)
.Returns(services.Object);
// Act
await page.ExecuteAsync();
// Assert
var actual = ((StringWriter)page.Output).ToString();
Assert.Equal(expected, actual);
helper.Verify();
}
private static TestableRazorPage CreatePage(Action<TestableRazorPage> executeAction)
{
var view = new Mock<TestableRazorPage> { CallBase = true };

View File

@ -1 +1 @@
@Html.Label("Hello") @Component.Invoke("Test", "world")
@Html.Label("Hello") @Component.Invoke("Test", "world") @Url.Action("ConsumeServicesFromBaseType")

View File

@ -1,2 +1 @@
@Href("~/content/scripts/test.js")
@Url.Action("ConsumeDefaultProperties")