Bladeren bron

Set StatusCode to 200 for ActionResult<T> that wraps an object value (#28267)

Summary of the changes
 - For `ActionResult<T>` that wraps an object value, set status code to 200 when converting to `IActionResult`
 - Special handling for `ProblemDetails` (honors `StatusCode` in `ProblemDetails` if it's set)

Addresses #27165
scharnyw 5 jaren geleden
bovenliggende
commit
bd4d9657e9
2 gewijzigde bestanden met toevoegingen van 42 en 2 verwijderingen
  1. 20 1
      src/Mvc/Mvc.Core/src/ActionResultOfT.cs
  2. 22 1
      src/Mvc/Mvc.Core/test/ActionResultOfTTest.cs

+ 20 - 1
src/Mvc/Mvc.Core/src/ActionResultOfT.cs

@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc.Core;
 using Microsoft.AspNetCore.Mvc.Infrastructure;
 
@@ -13,6 +14,8 @@ namespace Microsoft.AspNetCore.Mvc
     /// <typeparam name="TValue">The type of the result.</typeparam>
     public sealed class ActionResult<TValue> : IConvertToActionResult
     {
+        private const int DefaultStatusCode = StatusCodes.Status200OK;
+
         /// <summary>
         /// Initializes a new instance of <see cref="ActionResult{TValue}"/> using the specified <paramref name="value"/>.
         /// </summary>
@@ -73,9 +76,25 @@ namespace Microsoft.AspNetCore.Mvc
 
         IActionResult IConvertToActionResult.Convert()
         {
-            return Result ?? new ObjectResult(Value)
+            if (Result != null)
+            {
+                return Result;
+            }
+
+            int statusCode;
+            if (Value is ProblemDetails problemDetails && problemDetails.Status != null)
+            {
+                statusCode = problemDetails.Status.Value;
+            }
+            else
+            {
+                statusCode = DefaultStatusCode;
+            }
+
+            return new ObjectResult(Value)
             {
                 DeclaredType = typeof(TValue),
+                StatusCode = statusCode
             };
         }
     }

+ 22 - 1
src/Mvc/Mvc.Core/test/ActionResultOfTTest.cs

@@ -1,8 +1,9 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. 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.IO;
+using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc.Infrastructure;
 using Xunit;
 
@@ -62,6 +63,25 @@ namespace Microsoft.AspNetCore.Mvc
             var objectResult = Assert.IsType<ObjectResult>(result);
             Assert.Same(value, objectResult.Value);
             Assert.Equal(typeof(BaseItem), objectResult.DeclaredType);
+            Assert.Equal(StatusCodes.Status200OK, objectResult.StatusCode);
+        }
+
+        [Fact]
+        public void Convert_ReturnsObjectResultWrappingValue_SetsStatusCodeFromProblemDetails()
+        {
+            // Arrange
+            var value = new ProblemDetails { Status = StatusCodes.Status400BadRequest };
+            var actionResultOfT = new ActionResult<ProblemDetails>(value);
+            var convertToActionResult = (IConvertToActionResult)actionResultOfT;
+
+            // Act
+            var result = convertToActionResult.Convert();
+
+            // Assert
+            var objectResult = Assert.IsType<ObjectResult>(result);
+            Assert.Same(value, objectResult.Value);
+            Assert.Equal(typeof(ProblemDetails), objectResult.DeclaredType);
+            Assert.Equal(StatusCodes.Status400BadRequest, objectResult.StatusCode);
         }
 
         [Fact]
@@ -79,6 +99,7 @@ namespace Microsoft.AspNetCore.Mvc
             var objectResult = Assert.IsType<ObjectResult>(result);
             Assert.Same(value, objectResult.Value);
             Assert.Equal(typeof(BaseItem), objectResult.DeclaredType);
+            Assert.Equal(StatusCodes.Status200OK, objectResult.StatusCode);
         }
 
         private class BaseItem