ani*_*ina 12 c# asp.net-core-mvc asp.net-core asp.net-core-webapi
我想基于请求的accept头为同一个功能(实体列表)返回两个不同的格式化响应,它用于"json"和"html"请求.
asp.net核心是否支持根据请求中的Accept Header为同一路由选择不同的操作?
ani*_*ina 13
我潜入了.net核心源代码,并寻找其他类似行为的属性,如Microsoft.AspNetCore.Mvc.HttpGet
或Microsoft.AspNetCore.Mvc.ProducesAttribute
.这两个属性都实现了一个Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint
接口,aspnetcore.mvc使用该接口来控制控制器内部操作的选择.
所以我实现了一个简化的ProducesAttribute(一个"致敬")来检查接受头.
/// <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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用此属性修饰任何操作.
请注意,它很容易更改,并允许指定要检查的标头和值.
归档时间: |
|
查看次数: |
4898 次 |
最近记录: |