[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 destinationUrl = urlHelper.RouteUrl(RouteValues);
var destinationUrl = urlHelper.RouteUrl(RouteName, RouteValues);
if (string.IsNullOrEmpty(destinationUrl))
{
throw new InvalidOperationException(Resources.NoRoutesMatched);

View File

@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.Testing;
using Moq;
@ -97,6 +99,37 @@ namespace Microsoft.AspNet.Mvc.Core
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
{
get

View File

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

View File

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

View File

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

View File

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