Supporting Urls With ~/ while redirecting.
Fix for Issue#304
This commit is contained in:
parent
2ad5847132
commit
483e9038b4
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc
|
namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
|
|
@ -30,10 +31,18 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
public override void ExecuteResult([NotNull] ActionContext context)
|
public override void ExecuteResult([NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
// It is redirected directly to the input URL.
|
var destinationUrl = Url;
|
||||||
// We would use the context to construct the full URL,
|
var urlHelper = context.HttpContext
|
||||||
// only when relative URLs are supported. (Issue - WEBFX-202)
|
.RequestServices
|
||||||
context.HttpContext.Response.Redirect(Url, Permanent);
|
.GetService<IUrlHelper>();
|
||||||
|
|
||||||
|
// IsLocalUrl is called to handle Urls starting with '~/'.
|
||||||
|
if (urlHelper.IsLocalUrl(destinationUrl))
|
||||||
|
{
|
||||||
|
destinationUrl = urlHelper.Content(Url);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.HttpContext.Response.Redirect(destinationUrl, Permanent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||||
|
using Moq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
|
{
|
||||||
|
public class RedirectResultTest
|
||||||
|
{
|
||||||
|
[Theory]
|
||||||
|
[InlineData("", "/Home/About", "/Home/About")]
|
||||||
|
[InlineData("/myapproot", "/test", "/test")]
|
||||||
|
public void Execute_ReturnsContentPath_WhenItDoesNotStartWithTilde(string appRoot,
|
||||||
|
string contentPath,
|
||||||
|
string expectedPath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var httpResponse = new Mock<HttpResponse>();
|
||||||
|
httpResponse.Setup(o => o.Redirect(expectedPath, false))
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
|
var httpContext = GetHttpContext(appRoot, contentPath, expectedPath, httpResponse.Object);
|
||||||
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
var result = new RedirectResult(contentPath);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
result.ExecuteResult(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// Verifying if Redirect was called with the specific Url and parameter flag.
|
||||||
|
httpResponse.Verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(null, "~/Home/About", "/Home/About")]
|
||||||
|
[InlineData("/", "~/Home/About", "/Home/About")]
|
||||||
|
[InlineData("/", "~/", "/")]
|
||||||
|
[InlineData("", "~/Home/About", "/Home/About")]
|
||||||
|
[InlineData("/myapproot", "~/", "/myapproot/")]
|
||||||
|
[InlineData("", "~/Home/About", "/Home/About")]
|
||||||
|
[InlineData("/myapproot", "~/", "/myapproot/")]
|
||||||
|
public void Execute_ReturnsAppRelativePath_WhenItStartsWithTilde(string appRoot,
|
||||||
|
string contentPath,
|
||||||
|
string expectedPath)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var httpResponse = new Mock<HttpResponse>();
|
||||||
|
httpResponse.Setup(o => o.Redirect(expectedPath, false))
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
|
var httpContext = GetHttpContext(appRoot, contentPath, expectedPath, httpResponse.Object);
|
||||||
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
var result = new RedirectResult(contentPath);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
result.ExecuteResult(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// Verifying if Redirect was called with the specific Url and parameter flag.
|
||||||
|
httpResponse.Verify();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ActionContext GetActionContext(HttpContext httpContext)
|
||||||
|
{
|
||||||
|
return new ActionContext(httpContext,
|
||||||
|
Mock.Of<IRouter>(),
|
||||||
|
new Dictionary<string, object>(),
|
||||||
|
new ActionDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IServiceProvider GetServiceProvider(IUrlHelper urlHelper)
|
||||||
|
{
|
||||||
|
var serviceCollection = new ServiceCollection();
|
||||||
|
serviceCollection.AddInstance<IUrlHelper>(urlHelper);
|
||||||
|
return serviceCollection.BuildServiceProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpContext GetHttpContext(string appRoot,
|
||||||
|
string contentPath,
|
||||||
|
string expectedPath,
|
||||||
|
HttpResponse response)
|
||||||
|
{
|
||||||
|
var httpContext = new Mock<HttpContext>();
|
||||||
|
var actionContext = GetActionContext(httpContext.Object);
|
||||||
|
var mockContentAccessor = new Mock<IContextAccessor<ActionContext>>();
|
||||||
|
mockContentAccessor.SetupGet(o => o.Value).Returns(actionContext);
|
||||||
|
var mockActionSelector = new Mock<IActionSelector>();
|
||||||
|
var urlHelper = new UrlHelper(mockContentAccessor.Object, mockActionSelector.Object);
|
||||||
|
var serviceProvider = GetServiceProvider(urlHelper);
|
||||||
|
|
||||||
|
httpContext.Setup(o => o.Response)
|
||||||
|
.Returns(response);
|
||||||
|
httpContext.SetupGet(o => o.RequestServices)
|
||||||
|
.Returns(serviceProvider);
|
||||||
|
httpContext.Setup(o => o.Request.PathBase)
|
||||||
|
.Returns(new PathString(appRoot));
|
||||||
|
|
||||||
|
return httpContext.Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
<Compile Include="ActionExecutorTests.cs" />
|
<Compile Include="ActionExecutorTests.cs" />
|
||||||
<Compile Include="ActionResults\RedirectToActionResultTest.cs" />
|
<Compile Include="ActionResults\RedirectToActionResultTest.cs" />
|
||||||
<Compile Include="ActionResults\RedirectToRouteResultTest.cs" />
|
<Compile Include="ActionResults\RedirectToRouteResultTest.cs" />
|
||||||
|
<Compile Include="ActionResults\RedirectResultTest.cs" />
|
||||||
<Compile Include="ActionSelectionConventionTests.cs" />
|
<Compile Include="ActionSelectionConventionTests.cs" />
|
||||||
<Compile Include="AntiXsrf\AntiForgeryTokenSerializerTest.cs" />
|
<Compile Include="AntiXsrf\AntiForgeryTokenSerializerTest.cs" />
|
||||||
<Compile Include="AntiXsrf\ITokenProvider.cs" />
|
<Compile Include="AntiXsrf\ITokenProvider.cs" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue