rspec/rules/S6967/S6967_csharp.cs

212 lines
5.9 KiB
C#

using System.ComponentModel.DataAnnotations;
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
[assembly: ApiController] // This testcase should be on a dedicated test.
public class ControllerWithApiAttributeAtTheAssemblyLevel : ControllerBase
{
[HttpPost("/[controller]")]
public string Add(Movie movie) // Compliant, ApiController attribute is applied at the assembly level.
{
return "Hello!";
}
}
[ApiController]
public class ControllerWithApiAttributeAtTheClassLevel : ControllerBase
{
[HttpPost("/[controller]")]
public string Add(Movie movie) // Compliant, ApiController attribute is applied at the class level.
{
return "Hello!";
}
}
[Controller]
public class ControllerThatDoesNotInheritFromControllerBase
{
[HttpPost("/[controller]")]
public string Add(Movie movie) // Compliant, ModelState is not available in this context.
{
return "Hello!";
}
}
public class SimpleController
{
[HttpPost("/[controller]")]
public string Add(Movie movie) // Compliant, ModelState is not available in this context.
{
return "Hello!";
}
}
public class NonCompliantController : ControllerBase
{
[HttpGet("/[controller]")]
public string Get([Required, FromQuery] string id) // Noncompliant
{
return "Hello!";
}
[HttpPost("/[controller]")]
public string Post(Movie movie) // Noncompliant
{
return "Hello!";
}
[HttpPut("/[controller]")]
public string Put(Movie movie) // Noncompliant
{
return "Hello!";
}
[HttpDelete("/[controller]")]
public string Delete(Movie movie) // Noncompliant
{
return "Hello!";
}
[HttpPatch("/[controller]")]
public string Patch(Movie movie) // Noncompliant
{
return "Hello!";
}
[HttpGet]
[HttpPost]
[HttpPut]
[HttpDelete]
[HttpPatch]
[Route("/[controller]/mix")]
public string Mix([Required, FromQuery, EmailAddress] string email) // Noncompliant
{
return "Hello!";
}
[AcceptVerbs("GET")]
[Route("/[controller]/accept-verbs")]
public string AGet([Required] string id) // Noncompliant
{
return "Hello!";
}
[AcceptVerbs("POST")]
[Route("/[controller]/accept-verbs")]
public string APost(Movie movie) // Noncompliant
{
return "Hello!";
}
[AcceptVerbs("PUT")]
[Route("/[controller]/accept-verbs")]
public string APut(Movie movie) // Noncompliant
{
return "Hello!";
}
[AcceptVerbs("DELETE")]
[Route("/[controller]/accept-verbs")]
public string ADelete(Movie movie) // Noncompliant
{
return "Hello!";
}
[AcceptVerbs("PATCH")]
[Route("/[controller]/accept-verbs")]
public string APatch(Movie movie) // Noncompliant
{
return "Hello!";
}
[AcceptVerbs("GET", "POST", "PUT", "DELETE", "PATCH")]
[Route("/[controller]/many")]
public string Many([Required, FromQuery, EmailAddress] string email) // Noncompliant
{
return "Hello!";
}
[HttpPost("/[controller]/without-validation")]
public string DtoWithoutValidation(DtoWithoutValidation dto) // Compliant, DtoWithoutValidation does not have any validation attributes.
{
return "Hello!";
}
[HttpPost("/[controller]/custom-attribute-validation")]
public string DtoWithCustomAttribute([ClassicMovie] string title) // Noncompliant
{
return "Hello!";
}
[HttpPost("/[controller]/custom-validation")]
public string DtoImplementingIValidatableObject(ValidatableMovie movie) // Noncompliant
{
return "Hello!";
}
[ValidateModel]
[HttpPost("/[controller]/validation-filter")]
public string WithValidationFilter(ValidatableMovie movie) // Compliant, the model is validated by the ValidateModelAttribute filter.
{
return "Hello!";
}
[HttpPost("/[controller]/try-validate-model")]
public string CallsTryValidateModel([Required] string email) // Compliant, calls TryValidateModel
{
return TryValidateModel(email) ? "Hi!" : "Hello!";
}
[HttpGet("/[controller]/list")]
public string[] List() => null; // Compliant
}
public class Movie
{
[Required]
public string Title { get; set; }
[Range(1900, 2200)]
public int Year { get; set; }
}
public class DtoWithoutValidation
{
public int? Id { get; set; }
public string? Name { get; set; }
}
public class ClassicMovieAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
return ValidationResult.Success;
}
}
public class ValidatableMovie : IValidatableObject
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Title { get; set; } = null!;
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
yield return new ValidationResult("Title is required", new[] { nameof(Title) });
}
}
public class ValidateModelAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
context.Result = new BadRequestObjectResult(context.ModelState);
}
}
}