Handle request in actionfilter(WITHOUT action exist)

Pavlo Rishko 1 Reputation point
2020-11-25T08:21:37.99+00:00

Hello.

I need to handle HEAD request which sanded by Microsoft office excel, when user click on hyperlink.
I decided to use action filter to solve this problem, but I have requirement's that I can't add "[AcceptVerbs(HttpVerbs.Head | HttpVerbs.Get)]"(to handle HEAD and GET) requests and I need have only GET action(don't create HEAD action method). And just return status OK in to any Head request from "ms-office". But as I know It's impossible to handle HEAD request in action filter if you don't have appropriate HEAD action method.

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,157 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,252 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Yihui Sun-MSFT 801 Reputation points
    2020-11-26T05:56:05.42+00:00

    Hi @Pavlo Rishko ,

    When a Head request is received, you can switch it from Head to Get and then process it. In addition, you need to register the configuration in the WebApiConfig file so that all Get methods support Head requests.

    I wrote an example, you can refer to it.

    HomeController

    public class HomeController : Controller  
    {  
        public async Task<ActionResult> Index()  
        {  
             HttpClient client = new HttpClient();  
             client.BaseAddress = new Uri("https://localhost:44305/");  
             client.DefaultRequestHeaders.Accept.Clear();  
             client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));  
             HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Head, "api/values/Test");  
             HttpResponseMessage response = await client.SendAsync(request);  
             if (response.IsSuccessStatusCode)  
             {  
                 var result = response.StatusCode;  
             }  
             return View();  
         }  
    }  
    

    ValuesController

     public class ValuesController : ApiController  
     {  
         [HttpGet]  
         public IEnumerable<string> Test()  
         {  
             return new string[] { "value1", "value2" };  
         }  
     }  
    

    HeadHandler

     public class HeadHandler : DelegatingHandler  
     {  
         private const string Head = "IsHead";  
         protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)  
         {  
             if (request.Method == HttpMethod.Head)  
             {  
                 request.Method = HttpMethod.Get;  
                 request.Properties.Add(Head, true);  
             }  
             var response = await base.SendAsync(request, cancellationToken);  
             object isHead;  
             response.RequestMessage.Properties.TryGetValue(Head, out isHead);  
             if (isHead != null && ((bool)isHead))  
             {  
                 var oldContent = await response.Content.ReadAsByteArrayAsync();  
                 var content = new StringContent(string.Empty);  
                 content.Headers.Clear();  
                 foreach (var header in response.Content.Headers)  
                 {  
                     content.Headers.Add(header.Key, header.Value);  
                 }  
                 content.Headers.ContentLength = oldContent.Length;  
                 response.Content = content;  
             }  
             return response;  
         }  
     }  
    

    WebApiConfig

     public static class WebApiConfig  
     {  
         public static void Register(HttpConfiguration config)  
         {  
             config.MapHttpAttributeRoutes();  
             config.Routes.MapHttpRoute(  
                 name: "DefaultApi",  
                 routeTemplate: "api/{controller}/{action}/{id}",  
                 defaults: new { id = RouteParameter.Optional }  
             );  
             config.MessageHandlers.Add(new HeadHandler());  
         }  
     }  
    

    Here is the result.
    42876-capture.png


    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,
    YihuiSun

    0 comments No comments