[Fixes #2545] RedirectToRouteResult doesn't use RouteName property when calculating destination URL

This commit is contained in:
Kiran Challa 2015-05-12 16:06:21 -07:00
parent da740cd6a8
commit 4bed2e6f2b
6 changed files with 59 additions and 9 deletions

View File

@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Mvc
{ {
var urlHelper = GetUrlHelper(context); var urlHelper = GetUrlHelper(context);
var destinationUrl = urlHelper.RouteUrl(RouteValues); var destinationUrl = urlHelper.RouteUrl(RouteName, RouteValues);
if (string.IsNullOrEmpty(destinationUrl)) if (string.IsNullOrEmpty(destinationUrl))
{ {
throw new InvalidOperationException(Resources.NoRoutesMatched); throw new InvalidOperationException(Resources.NoRoutesMatched);

View File

@ -3,7 +3,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Testing; using Microsoft.AspNet.Testing;
using Moq; using Moq;
@ -97,6 +99,37 @@ namespace Microsoft.AspNet.Mvc.Core
tempData.Verify(t => t.Keep(), Times.Once()); tempData.Verify(t => t.Keep(), Times.Once());
} }
[Fact]
public async Task ExecuteResultAsync_UsesRouteName_ToGenerateLocationHeader()
{
// Arrange
var routeName = "orders_api";
var locationUrl = "/api/orders/10";
var urlHelper = new Mock<IUrlHelper>();
urlHelper.Setup(uh => uh.RouteUrl(It.IsAny<UrlRouteContext>()))
.Returns(locationUrl)
.Verifiable();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(sp => sp.GetService(typeof(IUrlHelper)))
.Returns(urlHelper.Object);
serviceProvider.Setup(sp => sp.GetService(typeof(ITempDataDictionary)))
.Returns(new Mock<ITempDataDictionary>().Object);
var httpContext = new DefaultHttpContext();
httpContext.RequestServices = serviceProvider.Object;
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new RedirectToRouteResult(routeName, new { id = 10 });
// Act
await result.ExecuteResultAsync(actionContext);
// Assert
urlHelper.Verify(uh => uh.RouteUrl(
It.Is<UrlRouteContext>(routeContext => string.Equals(routeName, routeContext.RouteName))));
Assert.True(httpContext.Response.Headers.ContainsKey("Location"), "Location header not found");
Assert.Equal(locationUrl, httpContext.Response.Headers["Location"]);
}
public static IEnumerable<object[]> RedirectToRouteData public static IEnumerable<object[]> RedirectToRouteData
{ {
get get

View File

@ -26,9 +26,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
private readonly Assembly _resourcesAssembly = typeof(LinkGenerationTests).GetTypeInfo().Assembly; private readonly Assembly _resourcesAssembly = typeof(LinkGenerationTests).GetTypeInfo().Assembly;
[Theory] [Theory]
[InlineData("http://pingüino/Home/RedirectToActionReturningTaskAction")] [InlineData("http://pingüino/Home/RedirectToActionReturningTaskAction", "/Home/ActionReturningTask")]
[InlineData("http://pingüino/Home/RedirectToRouteActionAsMethodAction")] [InlineData("http://pingüino/Home/RedirectToRouteActionAsMethodAction", "/Home/ActionReturningTask")]
public async Task GeneratedLinksWithActionResults_AreRelativeLinks_WhenSetOnLocationHeader(string url) [InlineData("http://pingüino/Home/RedirectToRouteUsingRouteName", "/api/orders/10")]
public async Task GeneratedLinksWithActionResults_AreRelativeLinks_WhenSetOnLocationHeader(
string url,
string expected)
{ {
// Arrange // Arrange
var server = TestHelper.CreateServer(_app, SiteName, _configureServices); var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
@ -43,7 +46,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Assert // Assert
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Equal("/Home/ActionReturningTask", response.Headers.Location.ToString()); Assert.Equal(expected, response.Headers.Location.ToString());
} }
[Fact] [Fact]

View File

@ -327,19 +327,23 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal("http://localhost/api/Users", response.Headers.Location.OriginalString); Assert.Equal("http://localhost/api/Users", response.Headers.Location.OriginalString);
} }
[Fact] [Theory]
public async Task ApiController_RedirectUri() [InlineData("http://localhost/api/Blog/ActionResult/GetRedirectUri", "api/Blog")]
[InlineData(
"http://localhost/api/Blog/ActionResult/GetRedirectUrlUsingRouteName",
"/api/Blog/BasicApi/WriteToHttpContext")]
public async Task ApiController_RedirectUri(string url, string expected)
{ {
// Arrange // Arrange
var server = TestHelper.CreateServer(_app, SiteName, _configureServices); var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient(); var client = server.CreateClient();
// Act // Act
var response = await client.GetAsync("http://localhost/api/Blog/ActionResult/GetRedirectUri"); var response = await client.GetAsync(url);
// Assert // Assert
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode); Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
Assert.Equal("api/Blog", response.Headers.Location.OriginalString); Assert.Equal(expected, response.Headers.Location.OriginalString);
} }
[Fact] [Fact]

View File

@ -37,6 +37,11 @@ namespace BasicWebSite.Controllers
return RedirectToRoute("ActionAsMethod", new { action = "ActionReturningTask", controller = "Home" }); return RedirectToRoute("ActionAsMethod", new { action = "ActionReturningTask", controller = "Home" });
} }
public IActionResult RedirectToRouteUsingRouteName()
{
return RedirectToRoute("OrdersApi", new { id = 10 });
}
public IActionResult NoContentResult() public IActionResult NoContentResult()
{ {
return new HttpStatusCodeResult(StatusCodes.Status204NoContent); return new HttpStatusCodeResult(StatusCodes.Status204NoContent);

View File

@ -120,6 +120,11 @@ namespace WebApiCompatShimWebSite
return Redirect(new Uri("api/Blog", UriKind.RelativeOrAbsolute)); return Redirect(new Uri("api/Blog", UriKind.RelativeOrAbsolute));
} }
public IActionResult GetRedirectUrlUsingRouteName()
{
return RedirectToRoute("named-action", new { controller = "BasicApi", action = "WriteToHttpContext" });
}
public IActionResult GetResponseMessage() public IActionResult GetResponseMessage()
{ {
var response = new HttpResponseMessage(HttpStatusCode.OK); var response = new HttpResponseMessage(HttpStatusCode.OK);