Accepting an ASPI for an Accept Main Web Application Based on Accept

I want to return two different formatted answers for the same function (list of entities) based on the accept header of the request, this is for the "json" and "html" request.

Does asp.net kernel support support different actions for the same Accept Header- based route from the request?

+5
source share
2 answers

I plunged into the source code of the .net kernel and looked for other attributes that perform similar behavior, such as Microsoft.AspNetCore.Mvc.HttpGet or Microsoft.AspNetCore.Mvc.ProducesAttribute . Both attributes implement the Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint interface, which is used by aspnetcore.mvc to control the selection of actions within the controller.

So, I used the simplified ProducesAttribute ("tribute") to validate 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.

Please note that it is easy to change it and allow it to indicate the title you want to check and the value.

+5
source
 if(Request.Headers["Content-Type"] == "application/json") { return OK(json); } else { return View(); } 

Good?

0
source

Source: https://habr.com/ru/post/1268171/


All Articles