基于Accept标头的ASP.NET Core Web API操作选择 [英] ASP.NET Core web api action selection based on Accept header

查看:198
本文介绍了基于Accept标头的ASP.NET Core Web API操作选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想基于请求的接受标头针对同一功能(实体列表)返回两种不同格式的响应,这是针对"json"和"html"请求的.

I want to return two different formatted responses for the same feature (a list of entities) based on the accept header of the request, it is for a "json" and a "html" request.

asp.net核心支持是否根据请求中的接受标头为同一路由选择不同的操作?

Does the asp.net core support select different actions for the same route based upon the Accept Header from the request?

推荐答案

我深入研究了.net核心源代码,并寻找了执行某些类似行为的其他属性,例如Microsoft.AspNetCore.Mvc.HttpGetMicrosoft.AspNetCore.Mvc.ProducesAttribute. 这两个属性都实现了Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint接口,aspnetcore.mvc使用该接口控制控制器内部动作的选择.

I dived into the .net core source code and looked for other attributes that do some similar behaviour such as Microsoft.AspNetCore.Mvc.HttpGet or Microsoft.AspNetCore.Mvc.ProducesAttribute. Both attributes implements an Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint interface wich is used by aspnetcore.mvc to control the selection of actions inside a controller.

因此,我实现了一个简化的ProducesAttribute(贡")来检查accept标头.

So i implemented a simplified ProducesAttribute (a "tribute") to check for the accept header.

    /// <summary>
    /// A filter that specifies the supported response content types. The request accept header is used to determine if it is a valid action
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class AcceptHeaderAttribute : Attribute, IActionConstraint
    {

        public AcceptHeaderAttribute(string contentType, params string[] otherContentTypes)
        {            
            if (contentType == null)
                throw new ArgumentNullException(nameof(contentType));

            // We want to ensure that the given provided content types are valid values, so
            // we validate them using the semantics of MediaTypeHeaderValue.
            MediaTypeHeaderValue.Parse(contentType);

            for (var i = 0; i < otherContentTypes.Length; i++)
            {
                MediaTypeHeaderValue.Parse(otherContentTypes[i]);
            }

            ContentTypes = GetContentTypes(contentType, otherContentTypes);
        }

        public MediaTypeCollection ContentTypes
        {
            get; set;
        }

        public int Order
        {
            get
            {
                return 0;
            }
        }

        private bool IsSubsetOfAnyContentType(string requestMediaType)
        {
            var parsedRequestMediaType = new MediaType(requestMediaType);
            for (var i = 0; i < ContentTypes.Count; i++)
            {
                var contentTypeMediaType = new MediaType(ContentTypes[i]);
                if (parsedRequestMediaType.IsSubsetOf(contentTypeMediaType))
                {
                    return true;
                }
            }
            return false;
        }

        public bool Accept(ActionConstraintContext context)
        {
            var requestAccept = context.RouteContext.HttpContext.Request.Headers[HeaderNames.Accept];
            if (StringValues.IsNullOrEmpty(requestAccept))
                return true;

            if (IsSubsetOfAnyContentType(requestAccept))
                return true;

            return false;
        }

        private MediaTypeCollection GetContentTypes(string firstArg, string[] args)
        {
            var completeArgs = new List<string>();
            completeArgs.Add(firstArg);
            completeArgs.AddRange(args);

            var contentTypes = new MediaTypeCollection();
            foreach (var arg in completeArgs)
            {
                contentTypes.Add(arg);
            }

            return contentTypes;
        }
    }

您可以使用此属性装饰任何动作.

You can decorate any action with this attribute.

请注意,它很容易更改,并允许指定要检查的标头和值.

Note that it is easy to change and allow to specify the header you want to check and the value.

这篇关于基于Accept标头的ASP.NET Core Web API操作选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆