[Fixes #5170] Fixed KeyNotFoundException in UrlHelperFactory.GetUrlHelper()

This commit is contained in:
Ajay Bhargav Baaskaran 2016-08-22 12:35:15 -07:00
parent 3aa6d739ce
commit 9ed753288f
2 changed files with 68 additions and 4 deletions

View File

@ -32,13 +32,15 @@ namespace Microsoft.AspNetCore.Mvc.Routing
} }
// Perf: Create only one UrlHelper per context // Perf: Create only one UrlHelper per context
var urlHelper = httpContext.Items[typeof(IUrlHelper)] as IUrlHelper; object value;
if (urlHelper == null) if (httpContext.Items.TryGetValue(typeof(IUrlHelper), out value) && value is IUrlHelper)
{ {
urlHelper = new UrlHelper(context); return (IUrlHelper)value;
httpContext.Items[typeof(IUrlHelper)] = urlHelper;
} }
var urlHelper = new UrlHelper(context);
httpContext.Items[typeof(IUrlHelper)] = urlHelper;
return urlHelper; return urlHelper;
} }
} }

View File

@ -971,6 +971,68 @@ namespace Microsoft.AspNetCore.Mvc.Routing
Assert.Equal(expected, url); Assert.Equal(expected, url);
} }
[Fact]
public void GetUrlHelper_ReturnsSameInstance_IfAlreadyPresent()
{
// Arrange
var expectedUrlHelper = CreateUrlHelper();
var httpContext = new Mock<HttpContext>();
var mockItems = new Dictionary<object, object>
{
{ typeof(IUrlHelper), expectedUrlHelper }
};
httpContext.Setup(h => h.Items).Returns(mockItems);
var actionContext = CreateActionContext(httpContext.Object, Mock.Of<IRouter>());
var urlHelperFactory = new UrlHelperFactory();
// Act
var urlHelper = urlHelperFactory.GetUrlHelper(actionContext);
// Assert
Assert.Same(expectedUrlHelper, urlHelper);
}
[Fact]
public void GetUrlHelper_CreatesNewInstance_IfNotAlreadyPresent()
{
// Arrange
var httpContext = new Mock<HttpContext>();
httpContext.Setup(h => h.Items).Returns(new Dictionary<object, object>());
var actionContext = CreateActionContext(httpContext.Object, Mock.Of<IRouter>());
var urlHelperFactory = new UrlHelperFactory();
// Act
var urlHelper = urlHelperFactory.GetUrlHelper(actionContext);
// Assert
Assert.NotNull(urlHelper);
Assert.Same(urlHelper, actionContext.HttpContext.Items[typeof(IUrlHelper)] as IUrlHelper);
}
[Fact]
public void GetUrlHelper_CreatesNewInstance_IfExpectedTypeIsNotPresent()
{
// Arrange
var httpContext = new Mock<HttpContext>();
var mockItems = new Dictionary<object, object>
{
{ typeof(IUrlHelper), null }
};
httpContext.Setup(h => h.Items).Returns(mockItems);
var actionContext = CreateActionContext(httpContext.Object, Mock.Of<IRouter>());
var urlHelperFactory = new UrlHelperFactory();
// Act
var urlHelper = urlHelperFactory.GetUrlHelper(actionContext);
// Assert
Assert.NotNull(urlHelper);
Assert.Same(urlHelper, actionContext.HttpContext.Items[typeof(IUrlHelper)] as IUrlHelper);
}
private static HttpContext CreateHttpContext( private static HttpContext CreateHttpContext(
IServiceProvider services, IServiceProvider services,
string appRoot) string appRoot)