From 51567194dce7d45c985856e4d32ab443a5356843 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Mon, 5 Jan 2015 13:18:34 -0800 Subject: [PATCH] deleted duplicate action results in WebapiCompatShim --- .../ActionResults/CreatedAtActionResult.cs | 8 +- .../ActionResults/CreatedAtRouteResult.cs | 3 +- .../ActionResults/BadRequestResult.cs | 22 --- .../CreatedAtRouteNegotiatedContentResult.cs | 65 --------- .../CreatedNegotiatedContentResult.cs | 52 ------- .../ActionResults/NegotiatedContentResult.cs | 7 +- .../ApiController.cs | 52 ++++--- .../ActionResultTests.cs | 6 +- .../ActionResults/BadRequestResultTest.cs | 28 ---- ...eatedAtRouteNegotiatedContentResultTest.cs | 130 ------------------ .../CreatedNegotiatedContentResultTest.cs | 111 --------------- .../ApiControllerTest.cs | 27 ++-- 12 files changed, 52 insertions(+), 459 deletions(-) delete mode 100644 src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/BadRequestResult.cs delete mode 100644 src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedAtRouteNegotiatedContentResult.cs delete mode 100644 src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedNegotiatedContentResult.cs delete mode 100644 test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/BadRequestResultTest.cs delete mode 100644 test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/CreatedAtRouteNegotiatedContentResultTest.cs delete mode 100644 test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/CreatedNegotiatedContentResultTest.cs diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtActionResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtActionResult.cs index 764b9bbc62..3e968f33e2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtActionResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtActionResult.cs @@ -56,9 +56,15 @@ namespace Microsoft.AspNet.Mvc /// protected override void OnFormatting([NotNull] ActionContext context) { + var request = context.HttpContext.Request; var urlHelper = UrlHelper ?? context.HttpContext.RequestServices.GetRequiredService(); - var url = urlHelper.Action(ActionName, ControllerName, RouteValues); + var url = urlHelper.Action( + ActionName, + ControllerName, + RouteValues, + request.Scheme, + request.Host.ToUriComponent()); if (string.IsNullOrEmpty(url)) { diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtRouteResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtRouteResult.cs index d1e99b447d..9020978d00 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtRouteResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/CreatedAtRouteResult.cs @@ -59,9 +59,10 @@ namespace Microsoft.AspNet.Mvc /// protected override void OnFormatting([NotNull] ActionContext context) { + var request = context.HttpContext.Request; var urlHelper = UrlHelper ?? context.HttpContext.RequestServices.GetRequiredService(); - var url = urlHelper.RouteUrl(RouteName, RouteValues); + var url = urlHelper.RouteUrl(RouteName, RouteValues, request.Scheme, request.Host.ToUriComponent()); if (string.IsNullOrEmpty(url)) { diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/BadRequestResult.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/BadRequestResult.cs deleted file mode 100644 index 447aa8e471..0000000000 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/BadRequestResult.cs +++ /dev/null @@ -1,22 +0,0 @@ -// 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.Net; -using Microsoft.AspNet.Mvc; - -namespace System.Web.Http -{ - /// - /// An action result that returns an empty response. - /// - public class BadRequestResult : HttpStatusCodeResult - { - /// - /// Initializes a new instance of the class. - /// - public BadRequestResult() - : base((int)HttpStatusCode.BadRequest) - { - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedAtRouteNegotiatedContentResult.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedAtRouteNegotiatedContentResult.cs deleted file mode 100644 index 28db5cabef..0000000000 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedAtRouteNegotiatedContentResult.cs +++ /dev/null @@ -1,65 +0,0 @@ -// 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.Collections.Generic; -using System.Net; -using System.Threading.Tasks; -using Microsoft.AspNet.Mvc; -using Microsoft.Framework.DependencyInjection; -using ShimResources = Microsoft.AspNet.Mvc.WebApiCompatShim.Resources; - -namespace System.Web.Http -{ - /// - /// Represents an action result that performs route generation and content negotiation and returns a - /// response when content negotiation succeeds. - /// - /// The type of content in the entity body. - public class CreatedAtRouteNegotiatedContentResult : NegotiatedContentResult - { - /// - /// Initializes a new instance of the class with the - /// values provided. - /// - /// The name of the route to use for generating the URL. - /// The route data to use for generating the URL. - /// The content value to negotiate and format in the entity body. - /// The formatters to use to negotiate and format the content. - public CreatedAtRouteNegotiatedContentResult( - [NotNull] string routeName, - [NotNull] IDictionary routeValues, - [NotNull] T content) - : base(HttpStatusCode.Created, content) - { - RouteName = routeName; - RouteValues = routeValues; - } - - /// - /// Gets the name of the route to use for generating the URL. - /// - public string RouteName { get; private set; } - - /// - /// Gets the route data to use for generating the URL. - /// - public IDictionary RouteValues { get; private set; } - - /// - public override Task ExecuteResultAsync(ActionContext context) - { - var request = context.HttpContext.Request; - var urlHelper = context.HttpContext.RequestServices.GetService(); - - var url = urlHelper.RouteUrl(RouteName, RouteValues, request.Scheme, request.Host.ToUriComponent()); - if (url == null) - { - throw new InvalidOperationException(ShimResources.FormatCreatedAtRoute_RouteFailed(RouteName)); - } - - context.HttpContext.Response.Headers.Add("Location", new string[] { url }); - - return base.ExecuteResultAsync(context); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedNegotiatedContentResult.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedNegotiatedContentResult.cs deleted file mode 100644 index ccd96f5380..0000000000 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/CreatedNegotiatedContentResult.cs +++ /dev/null @@ -1,52 +0,0 @@ -// 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.Net; -using System.Threading.Tasks; -using Microsoft.AspNet.Mvc; - -namespace System.Web.Http -{ - /// - /// Represents an action result that performs route generation and content negotiation and returns a - /// response when content negotiation succeeds. - /// - /// The type of content in the entity body. - public class CreatedNegotiatedContentResult : NegotiatedContentResult - { - /// - /// Initializes a new instance of the class with the values - /// provided. - /// - /// The location at which the content has been created. - /// The content value to negotiate and format in the entity body. - public CreatedNegotiatedContentResult(Uri location, T content) - : base(HttpStatusCode.Created, content) - { - Location = location; - } - - /// - /// Gets the location at which the content has been created. - /// - public Uri Location { get; private set; } - - /// - public override Task ExecuteResultAsync(ActionContext context) - { - string location; - if (Location.IsAbsoluteUri) - { - location = Location.AbsoluteUri; - } - else - { - location = Location.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); - } - - context.HttpContext.Response.Headers.Add("Location", new string[] { location }); - - return base.ExecuteResultAsync(context); - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/NegotiatedContentResult.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/NegotiatedContentResult.cs index bed9f4109a..c63ca5c707 100644 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/NegotiatedContentResult.cs +++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ActionResults/NegotiatedContentResult.cs @@ -21,15 +21,10 @@ namespace System.Web.Http public NegotiatedContentResult(HttpStatusCode statusCode, T content) : base(content) { - StatusCode = statusCode; + StatusCode = (int)statusCode; Content = content; } - /// - /// Gets the HTTP status code for the response message. - /// - public HttpStatusCode StatusCode { get; private set; } - /// /// Gets the content value to negotiate and format in the entity body. /// diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs index 8e040f4ec4..54ff8becf5 100644 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs +++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs @@ -1,7 +1,6 @@ // 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.Collections.Generic; using System.Net; using System.Net.Http; using System.Security.Principal; @@ -10,7 +9,6 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.WebApiCompatShim; -using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; using Newtonsoft.Json; @@ -146,54 +144,54 @@ namespace System.Web.Http } /// - /// Creates a (201 Created) with the specified values. + /// Creates a (201 Created) with the specified values. /// - /// The type of content in the entity body. /// /// The location at which the content has been created. Must be a relative or absolute URL. /// - /// The content value to negotiate and format in the entity body. - /// A with the specified values. + /// The content value to format in the entity body. + /// A with the specified values. [NonAction] - public virtual CreatedNegotiatedContentResult Created([NotNull] string location, [NotNull] T content) + public virtual CreatedResult Created([NotNull] string location, object content) { - return Created(new Uri(location, UriKind.RelativeOrAbsolute), content); + return new CreatedResult(location, content); } /// - /// Creates a (201 Created) with the specified values. + /// Creates a (201 Created) with the specified values. /// - /// The type of content in the entity body. /// The location at which the content has been created. - /// The content value to negotiate and format in the entity body. - /// A with the specified values. + /// The content value to format in the entity body. + /// A with the specified values. [NonAction] - public virtual CreatedNegotiatedContentResult Created([NotNull] Uri location, [NotNull] T content) + public virtual CreatedResult Created([NotNull] Uri uri, object content) { - return new CreatedNegotiatedContentResult(location, content); + string location; + if (uri.IsAbsoluteUri) + { + location = uri.AbsoluteUri; + } + else + { + location = uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped); + } + return Created(location, content); } /// - /// Creates a (201 Created) with the specified values. + /// Creates a (201 Created) with the specified values. /// - /// The type of content in the entity body. /// The name of the route to use for generating the URL. /// The route data to use for generating the URL. - /// The content value to negotiate and format in the entity body. - /// A with the specified values. + /// The content value to format in the entity body. + /// A with the specified values. [NonAction] - public virtual CreatedAtRouteNegotiatedContentResult CreatedAtRoute( + public virtual CreatedAtRouteResult CreatedAtRoute( [NotNull] string routeName, object routeValues, - [NotNull] T content) + object content) { - var values = routeValues as IDictionary; - if (values == null) - { - values = new RouteValueDictionary(routeValues); - } - - return new CreatedAtRouteNegotiatedContentResult(routeName, values, content); + return new CreatedAtRouteResult(routeName, routeValues, content); } /// (MockBehavior.Strict); - urlHelper - .Setup(u => u.RouteUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns("http://contoso.com/api/Products/5"); - - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(urlHelper.Object); - - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - - var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor()); - var result = new CreatedAtRouteNegotiatedContentResult( - "api_route", - new RouteValueDictionary(new { controller = "Products", id = 5 }), - new Product()); - - // Act - await result.ExecuteResultAsync(context); - - // Assert - Assert.Equal(201, context.HttpContext.Response.StatusCode); - } - - [Fact] - public async Task CreatedAtRouteNegotiatedContentResult_SetsLocation() - { - // Arrange - var urlHelper = new Mock(MockBehavior.Strict); - urlHelper - .Setup(u => u.RouteUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns("http://contoso.com/api/Products/5"); - - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(urlHelper.Object); - - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - - var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor()); - var result = new CreatedAtRouteNegotiatedContentResult( - "api_route", - new RouteValueDictionary(new { controller = "Products", id = 5 }), - new Product()); - - // Act - await result.ExecuteResultAsync(context); - - // Assert - Assert.Equal("http://contoso.com/api/Products/5", httpContext.Response.Headers["Location"]); - } - - [Fact] - public async Task CreatedAtRouteNegotiatedContentResult_Fails() - { - // Arrange - var urlHelper = new Mock(MockBehavior.Strict); - urlHelper - .Setup(u => u.RouteUrl(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Returns((string)null); - - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(urlHelper.Object); - - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - - var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor()); - var result = new CreatedAtRouteNegotiatedContentResult( - "api_route", - new RouteValueDictionary(new { controller = "Products", id = 5 }), - new Product()); - - // Act - var ex = await Assert.ThrowsAsync(async () => await result.ExecuteResultAsync(context)); - - // Assert - Assert.Equal("Failed to generate a URL using route 'api_route'.", ex.Message); - } - - private IServiceProvider CreateServices(IUrlHelper urlHelper) - { - var services = new Mock(MockBehavior.Strict); - - services - .Setup(s => s.GetService(typeof(IUrlHelper))) - .Returns(urlHelper); - - var formatters = new Mock(MockBehavior.Strict); - formatters - .SetupGet(f => f.OutputFormatters) - .Returns(new List() { new JsonOutputFormatter(), }); - - services - .Setup(s => s.GetService(typeof(IOutputFormattersProvider))) - .Returns(formatters.Object); - - return services.Object; - } - - private class Product - { - public int Id { get; set; } - - public string Name { get; set; } - }; - } -} -#endif \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/CreatedNegotiatedContentResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/CreatedNegotiatedContentResultTest.cs deleted file mode 100644 index ee2312c856..0000000000 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ActionResults/CreatedNegotiatedContentResultTest.cs +++ /dev/null @@ -1,111 +0,0 @@ -// 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. - -#if ASPNET50 -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Microsoft.AspNet.Mvc; -using Microsoft.AspNet.PipelineCore; -using Microsoft.AspNet.Routing; -using Moq; -using Xunit; - -namespace System.Web.Http -{ - public class CreatedNegotiatedContentResultTest - { - [Fact] - public async Task CreatedNegotiatedContentResult_SetsStatusCode() - { - // Arrange - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(); - - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - - var uri = new Uri("http://contoso.com"); - - var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor()); - var result = new CreatedNegotiatedContentResult(uri, new Product()); - - // Act - await result.ExecuteResultAsync(context); - - // Assert - Assert.Equal(201, context.HttpContext.Response.StatusCode); - } - - [Fact] - public async Task CreatedNegotiatedContentResult_SetsLocation_Uri() - { - // Arrange - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(); - - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - - var uri = new Uri("http://contoso.com"); - - var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor()); - var result = new CreatedNegotiatedContentResult(uri, new Product()); - - // Act - await result.ExecuteResultAsync(context); - - // Assert - Assert.Equal("http://contoso.com/", httpContext.Response.Headers["Location"]); - } - - [Theory] - [InlineData("http://contoso.com/Api/Products")] - [InlineData("/Api/Products")] - [InlineData("Products")] - public async Task CreatedNegotiatedContentResult_SetsLocation_String(string uri) - { - // Arrange - var httpContext = new DefaultHttpContext(); - httpContext.RequestServices = CreateServices(); - - var stream = new MemoryStream(); - httpContext.Response.Body = stream; - - var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor()); - var result = new CreatedNegotiatedContentResult( - new Uri(uri, UriKind.RelativeOrAbsolute), - new Product()); - - // Act - await result.ExecuteResultAsync(context); - - // Assert - Assert.Equal(uri, httpContext.Response.Headers["Location"]); - } - - private IServiceProvider CreateServices() - { - var services = new Mock(MockBehavior.Strict); - - var formatters = new Mock(MockBehavior.Strict); - formatters - .SetupGet(f => f.OutputFormatters) - .Returns(new List() { new JsonOutputFormatter(), }); - - services - .Setup(s => s.GetService(typeof(IOutputFormattersProvider))) - .Returns(formatters.Object); - - return services.Object; - } - - private class Product - { - public int Id { get; set; } - - public string Name { get; set; } - }; - } -} -#endif \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerTest.cs index 996baeffb3..41eef06657 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ApiControllerTest.cs @@ -1,6 +1,7 @@ // 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.Collections.Generic; using System.Net; using System.Net.Http; using System.Security.Claims; @@ -104,16 +105,16 @@ namespace System.Web.Http // Arrange var controller = new ConcreteApiController(); - var uri = new Uri("http://contoso.com"); + var uri = new Uri("http://contoso.com/"); var product = new Product(); // Act var result = controller.Created(uri, product); // Assert - var created = Assert.IsType>(result); - Assert.Same(product, created.Content); - Assert.Same(uri, created.Location); + var created = Assert.IsType(result); + Assert.Same(product, created.Value); + Assert.Equal(uri.OriginalString, created.Location); } [Theory] @@ -131,9 +132,9 @@ namespace System.Web.Http var result = controller.Created(uri, product); // Assert - var created = Assert.IsType>(result); - Assert.Same(product, created.Content); - Assert.Equal(uri, created.Location.OriginalString); + var created = Assert.IsType(result); + Assert.Same(product, created.Value); + Assert.Equal(uri, created.Location); } [Fact] @@ -148,8 +149,8 @@ namespace System.Web.Http var result = controller.CreatedAtRoute("api_route", new { controller = "Products" }, product); // Assert - var created = Assert.IsType>(result); - Assert.Same(product, created.Content); + var created = Assert.IsType(result); + Assert.Same(product, created.Value); Assert.Equal("api_route", created.RouteName); Assert.Equal("Products", created.RouteValues["controller"]); } @@ -167,11 +168,11 @@ namespace System.Web.Http var result = controller.CreatedAtRoute("api_route", values, product); // Assert - var created = Assert.IsType>(result); - Assert.Same(product, created.Content); + var created = Assert.IsType(result); + Assert.Same(product, created.Value); Assert.Equal("api_route", created.RouteName); Assert.Equal("Products", created.RouteValues["controller"]); - Assert.Same(values, created.RouteValues); + Assert.Equal>(values, created.RouteValues); } [Fact] @@ -200,7 +201,7 @@ namespace System.Web.Http // Assert var contentResult = Assert.IsType>(result); - Assert.Equal(HttpStatusCode.Found, contentResult.StatusCode); + Assert.Equal((int)HttpStatusCode.Found, contentResult.StatusCode); Assert.Equal(content, contentResult.Value); }