0

I have been working with Web API for well over a year, and haven't run into this problem before. I am really at my witt's end after spending hours googling, and looking at stack overflow posts etc. I am wondering if I just have some brain fart thing going on.

I have a controller where I want a get and a put against the same route:

[Route("api/strings")]
    [HttpGet]
    public IHttpActionResult GetStrings()
    {
        try
        {
            var siteStrings = svc.GetSiteStrings(_appId);
            return Ok(new { strings = siteStrings });
        }
        catch(Exception)
        {
            return InternalServerError();
        }

    }



    [HttpPut]
    [AcceptVerbs("PUT")]
    [Route("api/strings")]
    public IHttpActionResult PutString(String key, String text)
    {
        //TODO: add authorization to this one.
        try
        {
            if (svc.UpdateString(key, text, _appId))
            {
                return Ok();
            }
            return InternalServerError();
        }
        catch (Exception)
        {
            return InternalServerError();
        }
    }

My routing is just the default out of the box routing as can be seen here:

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

After a seeming eternity doing configs over and over based on so many other stack overflow questions about 405 errors, I realized that I can verify that mine is trying to route my PUT method to my GET's endpoint. However if I change the route on my put to something else, I always get a 404. I can't figure out why it is putting all my puts or posts through to my GET verb and thus saying that the action is not allowed on my route. I am sure I am just missing something trivial at this point but mental fatigue and tired eyes are just holding me back. Anyone see something stupid I am doing wrong?

Anik Saha
  • 4,313
  • 2
  • 26
  • 41
Danny
  • 308
  • 1
  • 4
  • 12
  • It could be this scenario (just what i guess): you deployed the first version of api (with GET only) to server 1. And then you added PUT method and deploy the updated one to server 2. But in your testing, web browser connects to server 1. – Yang You Jan 19 '16 at 01:46
  • This was all just while running on my local development laptop with IIS express. My problem was that I hadn't realized that PUT and POST would only populate one parameter from the request body. Once I put in a complex type (my own class definition that matched the incoming request body) the routing worked out and got to the PUT. Oddly it would fall back to the routing on the get if it couldn't model bind well on the PUT. – Danny Jan 20 '16 at 18:02

1 Answers1

0

All I had to do was create a class that my put has to model bind to rather than two parameters, and the routing started working. That is surprising, but I just had to do the following and it works:

public class temp
    {
        public String key { get; set; }
        public String text { get; set; }
    }


    [HttpPut]
    [AcceptVerbs("PUT")]
    [Route("api/strings/")]
    public IHttpActionResult PutString(temp data)
    {
        //TODO: add authorization to this one.
        try
        {
            if (svc.UpdateString(data.key, data.text, _appId))
            {
                return Ok();
            }
            return InternalServerError();
        }
        catch (Exception)
        {
            return InternalServerError();
        }
    }

Obviously I won't keep that temp class there, but it was a quick stab in the dark to see if the put would route correctly that way. Sure enough it did. Must be something in the model binding specs for Web API that I wasn't aware of.

Danny
  • 308
  • 1
  • 4
  • 12