Esempio n. 1
0
        /// <summary>
        /// As a <see cref="IResourceFilter"/>, this filter looks at the request and rejects it before going ahead if
        /// 1. The format in the request does not match any format in the map.
        /// 2. If there is a conflicting producesFilter.
        /// </summary>
        /// <param name="context">The <see cref="ResourceExecutingContext"/>.</param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var format = GetFormat(context);

            if (format == null)
            {
                // no format specified by user, so the filter is muted
                return;
            }

            var contentType = _options.FormatterMappings.GetMediaTypeMappingForFormat(format);

            if (contentType == null)
            {
                _logger.UnsupportedFormatFilterContentType(format);

                // no contentType exists for the format, return 404
                context.Result = new NotFoundResult();
                return;
            }

            // Determine media types this action supports.
            var responseTypeFilters = context.Filters.OfType <IApiResponseMetadataProvider>();
            var supportedMediaTypes = new MediaTypeCollection();

            foreach (var filter in responseTypeFilters)
            {
                filter.SetContentTypes(supportedMediaTypes);
            }

            // Check if support is adequate for requested media type.
            if (supportedMediaTypes.Count == 0)
            {
                _logger.ActionDoesNotExplicitlySpecifyContentTypes();
                return;
            }

            // We need to check if the action can generate the content type the user asked for. That is, treat the
            // request's format and IApiResponseMetadataProvider-provided content types similarly to an Accept
            // header and an output formatter's SupportedMediaTypes: Confirm action supports a more specific media
            // type than requested e.g. OK if "text/*" requested and action supports "text/plain".
            if (!IsSuperSetOfAnySupportedMediaType(contentType, supportedMediaTypes))
            {
                _logger.ActionDoesNotSupportFormatFilterContentType(contentType, supportedMediaTypes);
                context.Result = new NotFoundResult();
            }
        }