示例#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)
        {
            Log.UnsupportedFormatFilterContentType(_logger, 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)
        {
            Log.ActionDoesNotExplicitlySpecifyContentTypes(_logger);
            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))
        {
            Log.ActionDoesNotSupportFormatFilterContentType(_logger, contentType, supportedMediaTypes);
            context.Result = new NotFoundResult();
        }
    }