gpt4 book ai didi

c# - 基于 Accept header 的 ASP.NET Core Web API 操作选择

转载 作者:可可西里 更新时间:2023-11-01 08:22:22 24 4
gpt4 key购买 nike

我想根据请求的接受 header 为同一功能(实体列表)返回两个不同格式的响应,它是针对“json”和“html”请求。

asp.net core是否支持根据请求中的Accept Header为同一路由选择不同的 Action ?

最佳答案

我深入研究了 .net 核心源代码并寻找其他具有类似行为的属性,例如 Microsoft.AspNetCore.Mvc.HttpGetMicrosoft.AspNetCore.Mvc.ProducesAttribute。这两个属性都实现了一个 Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint 接口(interface),aspnetcore.mvc 使用该接口(interface)来控制 Controller 内的 Action 选择。

所以我实现了一个简化的 ProducesAttribute(一种“致敬”)来检查接受 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;
}
}

你可以用这个属性装饰任何 Action 。

请注意,它很容易更改并允许指定您要检查的 header 和值。

关于c# - 基于 Accept header 的 ASP.NET Core Web API 操作选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44156625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com