0

I have a problem that I don't know why is ocurring.

What I want is to call a method in my web api, the httpOptions verb should return me a HttpOkStatus but instead it returns a 404 error. This is only happening if I put the tag [Route("MyRoute")], otherwise it work perfectly.

My question is, why it does not work when I put the tag on it?.

I have this code

[Authorize]
    [RoutePrefix("api/MergedSchemas")]
    public class MergedSchemasController : ApiController
    {


        [HttpGet]
        [Route("Schemas")]
        public HttpResponseMessage GetSchemas(string formName)
        {
          //Some code
        }
}

In the Global.asax I have this code:

public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            GlobalConfiguration.Configuration.MessageHandlers.Add(new OptionsHttpMessageHandler());
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }

    public class OptionsHttpMessageHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request.Method == HttpMethod.Options)
            {
                var apiExplorer = 
                GlobalConfiguration.Configuration.Services.GetApiExplorer();

                var controllerRequested = request.GetRouteData().Values["controller"] as string;
                var supportedMethods = apiExplorer.ApiDescriptions.Where(d =>
                {
                    var controller = d.ActionDescriptor.ControllerDescriptor.ControllerName;
                    return string.Equals(
                        controller, controllerRequested, StringComparison.OrdinalIgnoreCase);
                })
                .Select(d => d.HttpMethod.Method)
                .Distinct();

                if (!supportedMethods.Any())
                    return Task.Factory.StartNew(
                        () => request.CreateResponse(HttpStatusCode.NotFound));

                return Task.Factory.StartNew(() =>
                {
                    var resp = new HttpResponseMessage(HttpStatusCode.OK);
                    resp.Headers.Add("Access-Control-Allow-Methods", string.Join(",", supportedMethods));
                    return resp;
                });
            }

            return base.SendAsync(request, cancellationToken);

        }
    }

The uri I am calling is : /api/MergedSchemas/Schemas?formName=frmBCOSEG

Thank you!

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • The tag Route() is expecting you to give it a route not a name. Example (Route[("api/action")] – Left panda Jan 19 '18 at 17:56
  • Yes but when I call the Options method it returns me and error. – Pablito0951 Jan 19 '18 at 17:57
  • what is an " Options method" you may want to show us some code – Left panda Jan 19 '18 at 17:58
  • I want to call the method with the HttpOptions verb and it should always return a HttpOkStatus, Wait a seccond, I will post some code. – Pablito0951 Jan 19 '18 at 18:00
  • When asking a question on SO, 99.99% of the time, we cannot help without code. In general its a good idea to always include pertinent code in the question. We're going to ask for it anyway. –  Jan 19 '18 at 18:01
  • There you go, some code :) – Pablito0951 Jan 19 '18 at 18:04
  • can you show us what's the url you're calling ? – Left panda Jan 19 '18 at 18:06
  • Have you enabled attribute routing? –  Jan 19 '18 at 18:08
  • /api/MergedSchemas/Schemas?formName=frmBCOSEG – Pablito0951 Jan 19 '18 at 18:08
  • @Amy mmm maybe not... How do I do that? – Pablito0951 Jan 19 '18 at 18:09
  • https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 –  Jan 19 '18 at 18:11
  • Oh, yes it is done ;( – Pablito0951 Jan 19 '18 at 18:12
  • The rout tag works good. The thing is that when i call that method with HttpOptions verb, it does not work. – Pablito0951 Jan 19 '18 at 18:13
  • You specified `HttpGet`, so the Action will only react to GET requests, not to OPTIONS requests.... – NineBerry Jan 19 '18 at 18:14
  • Possible duplicate of [How to support HTTP OPTIONS verb in ASP.NET MVC/WebAPI application](https://stackoverflow.com/questions/19095777/how-to-support-http-options-verb-in-asp-net-mvc-webapi-application) – NineBerry Jan 19 '18 at 18:16
  • @NineBerry it response to options becouse of the code that I wrote in OptionsHttpMessageHandler class. The prove is that if I remove the route tag it response to HttpOptions. – Pablito0951 Jan 19 '18 at 18:17
  • It's unclear why you deleted your [first question](https://stackoverflow.com/questions/48343747/cant-use-my-web-api-with-option-verb-web-api-asp-net-c-sharp#comment83673038_48343747) about this, just to ask it again. –  Jan 19 '18 at 18:19
  • "What I want is to call a method in my web api, the options should return me a HttpOkStatus but instead it returns a 404 error. This is only happening if I put the tag [Route("MyRoute")], otherwise it work perfectly.". I thought that in that sentece I included it. Sorry, english is not my first lenguage as you can tell haha. – Pablito0951 Jan 19 '18 at 18:20
  • I think what is wrong is with this line: var controllerRequested = request.GetRouteData().Values["controller"] as string; in OptionsHttpMessageHandler class. Probably is not getting the route correctly becouse of the tags – Pablito0951 Jan 19 '18 at 18:31
  • @PabloSalazar, `request.GetRouteData().Values["controller"]` only runs `if(request.Method == HttpMethod.Options)` which is not the case, as you call your api using http verb GET, not OPTIONS. I have tested your code and it works here. The issue cannot be reproduced using what you posted in your question. – derloopkat Jan 19 '18 at 19:57

0 Answers0