Add analyzer support for status code methods and constructors
This commit is contained in:
parent
2a426dfea5
commit
ffdbea9dc1
|
|
@ -123,7 +123,7 @@ namespace Microsoft.CodeAnalysis
|
|||
return false;
|
||||
}
|
||||
|
||||
private static bool HasAttribute(this ISymbol symbol, ITypeSymbol attribute)
|
||||
public static bool HasAttribute(this ISymbol symbol, ITypeSymbol attribute)
|
||||
{
|
||||
foreach (var declaredAttribute in symbol.GetAttributes())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -116,6 +116,11 @@ namespace Microsoft.AspNetCore.Mvc.Analyzers
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!method.ReturnsVoid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (method.Parameters.Length != disposableDispose.Parameters.Length)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -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 System.Diagnostics;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
||||
|
|
@ -24,6 +25,11 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
ProducesDefaultResponseTypeAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ProducesDefaultResponseTypeAttribute);
|
||||
ProducesResponseTypeAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.ProducesResponseTypeAttribute);
|
||||
|
||||
StatusCodeValueAttribute = compilation.GetTypeByMetadataName(ApiSymbolNames.StatusCodeValueAttribute);
|
||||
|
||||
var statusCodeActionResult = compilation.GetTypeByMetadataName(ApiSymbolNames.IStatusCodeActionResult);
|
||||
StatusCodeActionResultStatusProperty = (IPropertySymbol)statusCodeActionResult.GetMembers("StatusCode")[0];
|
||||
|
||||
var disposable = compilation.GetSpecialType(SpecialType.System_IDisposable);
|
||||
var members = disposable.GetMembers(nameof(IDisposable.Dispose));
|
||||
IDisposableDispose = members.Length == 1 ? (IMethodSymbol)members[0] : null;
|
||||
|
|
@ -47,6 +53,8 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
|
||||
public IMethodSymbol IDisposableDispose { get; }
|
||||
|
||||
public IPropertySymbol StatusCodeActionResultStatusProperty { get; }
|
||||
|
||||
public ITypeSymbol ModelStateDictionary { get; }
|
||||
|
||||
public INamedTypeSymbol NonActionAttribute { get; }
|
||||
|
|
@ -56,5 +64,7 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
public INamedTypeSymbol ProducesDefaultResponseTypeAttribute { get; }
|
||||
|
||||
public INamedTypeSymbol ProducesResponseTypeAttribute { get; }
|
||||
|
||||
public INamedTypeSymbol StatusCodeValueAttribute { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
|
||||
public const string IActionResult = "Microsoft.AspNetCore.Mvc.IActionResult";
|
||||
|
||||
public const string IStatusCodeActionResult = "Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult";
|
||||
|
||||
public const string ModelStateDictionary = "Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary";
|
||||
|
||||
public const string NonActionAttribute = "Microsoft.AspNetCore.Mvc.NonActionAttribute";
|
||||
|
|
@ -34,5 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
public const string ProducesResponseTypeAttribute = "Microsoft.AspNetCore.Mvc.ProducesResponseTypeAttribute";
|
||||
|
||||
public const string HttpStatusCodes = "Microsoft.AspNetCore.Http.StatusCodes";
|
||||
|
||||
public const string StatusCodeValueAttribute = "Microsoft.AspNetCore.Mvc.Infrastructure.StatusCodeValueAttribute";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
}
|
||||
|
||||
return Array.Empty<DeclaredApiResponseMetadata>();
|
||||
}
|
||||
}
|
||||
|
||||
private static IMethodSymbol GetMethodFromConventionMethodAttribute(ApiControllerSymbolCache symbolCache, IMethodSymbol method)
|
||||
{
|
||||
var attribute = method.GetAttributes(symbolCache.ApiConventionMethodAttribute, inherit: true)
|
||||
|
|
@ -222,6 +223,12 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
|
||||
foreach (var returnStatementSyntax in methodSyntax.DescendantNodes(_shouldDescendIntoChildren).OfType<ReturnStatementSyntax>())
|
||||
{
|
||||
if (returnStatementSyntax.IsMissing || returnStatementSyntax.Expression.IsMissing)
|
||||
{
|
||||
// Ignore malformed return statements.
|
||||
continue;
|
||||
}
|
||||
|
||||
var responseMetadata = InspectReturnStatementSyntax(
|
||||
symbolCache,
|
||||
semanticModel,
|
||||
|
|
@ -248,11 +255,6 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
CancellationToken cancellationToken)
|
||||
{
|
||||
var returnExpression = returnStatementSyntax.Expression;
|
||||
if (returnExpression.IsMissing)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var typeInfo = semanticModel.GetTypeInfo(returnExpression, cancellationToken);
|
||||
if (typeInfo.Type.TypeKind == TypeKind.Error)
|
||||
{
|
||||
|
|
@ -267,25 +269,176 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
|
||||
if (defaultStatusCodeAttribute != null)
|
||||
{
|
||||
var statusCode = GetDefaultStatusCode(defaultStatusCodeAttribute);
|
||||
if (statusCode == null)
|
||||
var defaultStatusCode = GetDefaultStatusCode(defaultStatusCodeAttribute);
|
||||
if (defaultStatusCode == null)
|
||||
{
|
||||
// Unable to read the status code even though the attribute exists.
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ActualApiResponseMetadata(returnStatementSyntax, statusCode.Value);
|
||||
return new ActualApiResponseMetadata(returnStatementSyntax, defaultStatusCode.Value);
|
||||
}
|
||||
else if (!symbolCache.IActionResult.IsAssignableFrom(statementReturnType))
|
||||
|
||||
if (!symbolCache.IActionResult.IsAssignableFrom(statementReturnType))
|
||||
{
|
||||
// Return expression does not have a DefaultStatusCodeAttribute and it is not
|
||||
// an instance of IActionResult. Must be returning the "model".
|
||||
return new ActualApiResponseMetadata(returnStatementSyntax);
|
||||
}
|
||||
|
||||
int statusCode;
|
||||
switch (returnExpression)
|
||||
{
|
||||
case InvocationExpressionSyntax invocation:
|
||||
// Covers the 'return StatusCode(200)' case.
|
||||
if (TryGetParameterStatusCode(symbolCache, semanticModel, invocation.Expression, invocation.ArgumentList, cancellationToken, out statusCode))
|
||||
{
|
||||
return new ActualApiResponseMetadata(returnStatementSyntax, statusCode);
|
||||
}
|
||||
break;
|
||||
|
||||
case ObjectCreationExpressionSyntax creation:
|
||||
// Covers the 'return new ObjectResult(...) { StatusCode = 200 }' case.
|
||||
if (TryGetInitializerStatusCode(symbolCache, semanticModel, creation.Initializer, cancellationToken, out statusCode))
|
||||
{
|
||||
return new ActualApiResponseMetadata(returnStatementSyntax, statusCode);
|
||||
}
|
||||
|
||||
// Covers the 'return new StatusCodeResult(200) case.
|
||||
if (TryGetParameterStatusCode(symbolCache, semanticModel, creation, creation.ArgumentList, cancellationToken, out statusCode))
|
||||
{
|
||||
return new ActualApiResponseMetadata(returnStatementSyntax, statusCode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool TryGetInitializerStatusCode(
|
||||
in ApiControllerSymbolCache symbolCache,
|
||||
SemanticModel semanticModel,
|
||||
InitializerExpressionSyntax initializer,
|
||||
CancellationToken cancellationToken,
|
||||
out int statusCode)
|
||||
{
|
||||
if (initializer == null)
|
||||
{
|
||||
statusCode = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < initializer.Expressions.Count; i++)
|
||||
{
|
||||
if (!(initializer.Expressions[i] is AssignmentExpressionSyntax assignment))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (assignment.Left is IdentifierNameSyntax identifier)
|
||||
{
|
||||
var symbolInfo = semanticModel.GetSymbolInfo(identifier, cancellationToken);
|
||||
|
||||
if (symbolInfo.Symbol is IPropertySymbol property && IsInterfaceImplementation(property, symbolCache.StatusCodeActionResultStatusProperty))
|
||||
{
|
||||
return TryGetExpressionStatusCode(semanticModel, assignment.Right, cancellationToken, out statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statusCode = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsInterfaceImplementation(IPropertySymbol property, IPropertySymbol statusCodeActionResultStatusProperty)
|
||||
{
|
||||
if (property.Name != statusCodeActionResultStatusProperty.Name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < property.ExplicitInterfaceImplementations.Length; i++)
|
||||
{
|
||||
if (property.ExplicitInterfaceImplementations[i] == statusCodeActionResultStatusProperty)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var implementedProperty = property.ContainingType.FindImplementationForInterfaceMember(statusCodeActionResultStatusProperty);
|
||||
return implementedProperty == property;
|
||||
}
|
||||
|
||||
private static bool TryGetParameterStatusCode(
|
||||
in ApiControllerSymbolCache symbolCache,
|
||||
SemanticModel semanticModel,
|
||||
ExpressionSyntax expression,
|
||||
BaseArgumentListSyntax argumentList,
|
||||
CancellationToken cancellationToken,
|
||||
out int statusCode)
|
||||
{
|
||||
var symbolInfo = semanticModel.GetSymbolInfo(expression, cancellationToken);
|
||||
|
||||
if (!(symbolInfo.Symbol is IMethodSymbol method))
|
||||
{
|
||||
statusCode = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < method.Parameters.Length; i++)
|
||||
{
|
||||
var parameter = method.Parameters[i];
|
||||
if (!parameter.HasAttribute(symbolCache.StatusCodeValueAttribute))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var argument = argumentList.Arguments[parameter.Ordinal];
|
||||
return TryGetExpressionStatusCode(semanticModel, argument.Expression, cancellationToken, out statusCode);
|
||||
}
|
||||
|
||||
statusCode = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool TryGetExpressionStatusCode(
|
||||
SemanticModel semanticModel,
|
||||
ExpressionSyntax expression,
|
||||
CancellationToken cancellationToken,
|
||||
out int statusCode)
|
||||
{
|
||||
if (expression is LiteralExpressionSyntax literal && literal.Token.Value is int literalStatusCode)
|
||||
{
|
||||
// Covers the 'return StatusCode(200)' case.
|
||||
statusCode = literalStatusCode;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expression is IdentifierNameSyntax || expression is MemberAccessExpressionSyntax)
|
||||
{
|
||||
var symbolInfo = semanticModel.GetSymbolInfo(expression, cancellationToken);
|
||||
|
||||
if (symbolInfo.Symbol is IFieldSymbol field && field.HasConstantValue && field.ConstantValue is int constantStatusCode)
|
||||
{
|
||||
// Covers the 'return StatusCode(StatusCodes.Status200OK)' case.
|
||||
// It also covers the 'return StatusCode(StatusCode)' case, where 'StatusCode' is a constant field.
|
||||
statusCode = constantStatusCode;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (symbolInfo.Symbol is ILocalSymbol local && local.HasConstantValue && local.ConstantValue is int localStatusCode)
|
||||
{
|
||||
// Covers the 'return StatusCode(statusCode)' case, where 'statusCode' is a local constant.
|
||||
statusCode = localStatusCode;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
statusCode = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ShouldDescendIntoChildren(SyntaxNode syntaxNode)
|
||||
{
|
||||
return !syntaxNode.IsKind(SyntaxKind.LocalFunctionStatement) &&
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Core;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Internal;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
|
|
@ -200,7 +201,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
/// <param name="statusCode">The status code to set on the response.</param>
|
||||
/// <returns>The created <see cref="StatusCodeResult"/> object for the response.</returns>
|
||||
[NonAction]
|
||||
public virtual StatusCodeResult StatusCode(int statusCode)
|
||||
public virtual StatusCodeResult StatusCode([StatusCodeValue] int statusCode)
|
||||
=> new StatusCodeResult(statusCode);
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -210,10 +211,12 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
/// <param name="value">The value to set on the <see cref="ObjectResult"/>.</param>
|
||||
/// <returns>The created <see cref="ObjectResult"/> object for the response.</returns>
|
||||
[NonAction]
|
||||
public virtual ObjectResult StatusCode(int statusCode, object value)
|
||||
public virtual ObjectResult StatusCode([StatusCodeValue] int statusCode, object value)
|
||||
{
|
||||
var result = new ObjectResult(value);
|
||||
result.StatusCode = statusCode;
|
||||
var result = new ObjectResult(value)
|
||||
{
|
||||
StatusCode = statusCode
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class StatusCodeValueAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Mvc
|
|||
/// with the given <paramref name="statusCode"/>.
|
||||
/// </summary>
|
||||
/// <param name="statusCode">The HTTP status code of the response.</param>
|
||||
public StatusCodeResult(int statusCode)
|
||||
public StatusCodeResult([StatusCodeValue] int statusCode)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,18 @@ namespace Microsoft.AspNetCore.Mvc.Api.Analyzers
|
|||
[Fact]
|
||||
public Task CodeFixAddsFullyQualifiedProducesResponseType() => RunTest();
|
||||
|
||||
[Fact]
|
||||
public Task CodeFixAddsNumericLiteralForNonExistingStatusCodeConstants() => RunTest();
|
||||
|
||||
[Fact]
|
||||
public Task CodeFixAddsStatusCodesFromMethodParameters() => RunTest();
|
||||
|
||||
[Fact]
|
||||
public Task CodeFixAddsStatusCodesFromConstructorParameters() => RunTest();
|
||||
|
||||
[Fact]
|
||||
public Task CodeFixAddsStatusCodesFromObjectInitializer() => RunTest();
|
||||
|
||||
private async Task RunTest([CallerMemberName] string testMethod = "")
|
||||
{
|
||||
// Arrange
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsNumericLiteralForNonExistingStatusCodeConstantsController : ControllerBase
|
||||
{
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return StatusCode(345);
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsNumericLiteralForNonExistingStatusCodeConstantsController : ControllerBase
|
||||
{
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(345)]
|
||||
[ProducesDefaultResponseType]
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return StatusCode(345);
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsStatusCodesFromConstructorParametersController : ControllerBase
|
||||
{
|
||||
private const int FieldStatusCode = 201;
|
||||
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return new StatusCodeResult(422);
|
||||
}
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
return new StatusCodeResult(StatusCodes.Status202Accepted);
|
||||
}
|
||||
|
||||
if (id == 2)
|
||||
{
|
||||
const int localStatusCode = 204;
|
||||
|
||||
return new StatusCodeResult(localStatusCode);
|
||||
}
|
||||
|
||||
if (id == 3)
|
||||
{
|
||||
return new StatusCodeResult(FieldStatusCode);
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsStatusCodesFromConstructorParametersController : ControllerBase
|
||||
{
|
||||
private const int FieldStatusCode = 201;
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
|
||||
[ProducesDefaultResponseType]
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return new StatusCodeResult(422);
|
||||
}
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
return new StatusCodeResult(StatusCodes.Status202Accepted);
|
||||
}
|
||||
|
||||
if (id == 2)
|
||||
{
|
||||
const int localStatusCode = 204;
|
||||
|
||||
return new StatusCodeResult(localStatusCode);
|
||||
}
|
||||
|
||||
if (id == 3)
|
||||
{
|
||||
return new StatusCodeResult(FieldStatusCode);
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsStatusCodesFromMethodParametersController : ControllerBase
|
||||
{
|
||||
private const int FieldStatusCode = 201;
|
||||
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return StatusCode(422);
|
||||
}
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status202Accepted);
|
||||
}
|
||||
|
||||
if (id == 2)
|
||||
{
|
||||
const int localStatusCode = 204;
|
||||
|
||||
return StatusCode(localStatusCode);
|
||||
}
|
||||
|
||||
if (id == 3)
|
||||
{
|
||||
return StatusCode(FieldStatusCode);
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsStatusCodesFromMethodParametersController : ControllerBase
|
||||
{
|
||||
private const int FieldStatusCode = 201;
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
|
||||
[ProducesDefaultResponseType]
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return StatusCode(422);
|
||||
}
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status202Accepted);
|
||||
}
|
||||
|
||||
if (id == 2)
|
||||
{
|
||||
const int localStatusCode = 204;
|
||||
|
||||
return StatusCode(localStatusCode);
|
||||
}
|
||||
|
||||
if (id == 3)
|
||||
{
|
||||
return StatusCode(FieldStatusCode);
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._INPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsStatusCodesFromObjectInitializerController : ControllerBase
|
||||
{
|
||||
private const int FieldStatusCode = 201;
|
||||
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
StatusCode = 422
|
||||
};
|
||||
}
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
StatusCode = StatusCodes.Status202Accepted
|
||||
};
|
||||
}
|
||||
|
||||
if (id == 2)
|
||||
{
|
||||
const int localStatusCode = 204;
|
||||
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
StatusCode = localStatusCode
|
||||
};
|
||||
}
|
||||
|
||||
if (id == 3)
|
||||
{
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
ContentTypes = { "application/json" },
|
||||
StatusCode = FieldStatusCode
|
||||
};
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Api.Analyzers._OUTPUT_
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CodeFixAddsStatusCodesFromObjectInitializerController : ControllerBase
|
||||
{
|
||||
private const int FieldStatusCode = 201;
|
||||
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status201Created)]
|
||||
[ProducesResponseType(StatusCodes.Status202Accepted)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
|
||||
[ProducesDefaultResponseType]
|
||||
public IActionResult GetItem(int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
StatusCode = 422
|
||||
};
|
||||
}
|
||||
|
||||
if (id == 1)
|
||||
{
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
StatusCode = StatusCodes.Status202Accepted
|
||||
};
|
||||
}
|
||||
|
||||
if (id == 2)
|
||||
{
|
||||
const int localStatusCode = 204;
|
||||
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
StatusCode = localStatusCode
|
||||
};
|
||||
}
|
||||
|
||||
if (id == 3)
|
||||
{
|
||||
return new ObjectResult(new object())
|
||||
{
|
||||
ContentTypes = { "application/json" },
|
||||
StatusCode = FieldStatusCode
|
||||
};
|
||||
}
|
||||
|
||||
return Ok(new object());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue