IActionConstraint Asp. Net Порядок тестирования ядра - PullRequest
1 голос
/ 28 января 2020

Я создал собственный атрибут, реализующий IActionConstraint для фильтрации метода контроллера по типу носителя ввода, однако я не понимаю, почему мое ограничение не проверяется для каждого действия, а его возвращение ложно. У вас есть идея? Также кажется порядок метода в тестировании ограничений воздействия контроллера.

Спасибо за вашу помощь.

Пользовательская IActionConstraint:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;

namespace CourseLibrary.API.ActionConstraints
{
    [AttributeUsage(AttributeTargets.All,  AllowMultiple = true)]
    public class RequestHeaderMatchesMediaTypeAttribute: Attribute, IActionConstraint
    {
        private readonly string _requestHeaderToMatch;
        private readonly MediaTypeCollection _mediaTypes = new MediaTypeCollection();

        public RequestHeaderMatchesMediaTypeAttribute(string requestHeaderToMatch, string mediaType, params string[] otherMediaTypes)
        {
            _requestHeaderToMatch = requestHeaderToMatch ?? throw new ArgumentNullException(nameof(requestHeaderToMatch));
            var mediaTypes = new List<string>(){mediaType};

            foreach (var otherMediaType in otherMediaTypes)
            {
                mediaTypes.Add(otherMediaType);
            }
            SetMediaTypes(mediaTypes);
        }

        public bool Accept(ActionConstraintContext context)
        {
            var headers = context.RouteContext.HttpContext.Request.Headers;
            if (!headers.ContainsKey(_requestHeaderToMatch))
            {
                return false;
            }

            var parsedRequestMediaType = new MediaType(headers[_requestHeaderToMatch]);

            return _mediaTypes.Select(mediaType => new MediaType(mediaType)).Contains(parsedRequestMediaType);
        }

        public int Order => HttpMethodActionConstraint.HttpMethodConstraintOrder + 1 ;

        private void SetMediaTypes(IEnumerable<string> mediaTypes)
        {
            foreach (var mediaType in mediaTypes)
            {
                if (MediaTypeHeaderValue.TryParse(mediaType, out var parsedMediaType))
                {
                    _mediaTypes.Add(parsedMediaType);
                }
                else
                {
                    throw new ArgumentException(nameof(mediaType));
                }
            }
        }
    }
}

Контроллер:

using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using CourseLibrary.API.ActionConstraints;
using CourseLibrary.API.Entities;
using CourseLibrary.API.Helpers.Extensions;
using CourseLibrary.API.Helpers.Pagination;
using CourseLibrary.API.Models;
using CourseLibrary.API.Models.Authors;
using CourseLibrary.API.ResourceParameters;
using CourseLibrary.API.Services.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace CourseLibrary.API.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class AuthorsController : ControllerBase
    {
        [RequestHeaderMatchesMediaType("Content-Type", 
            "application/json","application/vnd.marvin.authorforcreation+json")]
        [Consumes("application/json", "application/vnd.marvin.authorforcreation+json")]
        [HttpPost(Name = "CreateAuthor")]
        public IActionResult CreateAuthor(AuthorForCreationDto authorForCreationDto)
        {
            var authorForCreation = _mapper.Map<Author>(authorForCreationDto);
            _courseLibraryRepository.AddAuthor(authorForCreation);
            _courseLibraryRepository.Save();
            var createdAuthor = _mapper.Map<AuthorDto>(authorForCreation);
            var links = GetLinksForAuthor(createdAuthor.Id);
            var linkedResourceToReturn = createdAuthor.ShapeData() as IDictionary<string, object>;
            linkedResourceToReturn.Add("links",links);
            return CreatedAtRoute("GetAuthor",new {authorId = createdAuthor.Id}, linkedResourceToReturn);
        }

        [RequestHeaderMatchesMediaType("Content-Type",
            "application/vnd.marvin.authorforcreationwithdateofdeath+json")]
        [Consumes( "application/vnd.marvin.authorforcreationwithdateofdeath+json")]
        [HttpPost(Name = "CreateAuthorWithDateOfDeath")]
        public IActionResult CreateAuthorWithDateOfDeath(AuthorCreationWithDateOfDeathDto authorCreationWithDateOfDeathDto)
        {
            return CreateAuthor(authorCreationWithDateOfDeathDto);
        }


}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...