Search code examples
asp.net-web-api2attributerouting

Web API 2 Post 404s, but Get works


I'm confused... I have a very simple Web API and controller, which works fine if I have a GET request, but 404's if I have a POST request.

[RoutePrefix("api/telemetry/trial")]
public class LoginTelemetryController : ApiController
{
    [Route("login")]
    [HttpPost]
    public IHttpActionResult RecordLogin(string appKey) {
        using (var context = new Core.Data.CoreContext()) {
            context.ActivityLogItems.Add(new Domain.Logging.ActivityLogItem()
            {
                ActivityType = "Trial.Login",
                DateUtc = DateTime.UtcNow,
                Key = new Guid(appKey)
            });
            context.SaveChanges();
        }
        return Ok();
    }

When I post against this in postman, I get:

{
    "message": "No HTTP resource was found that matches the request URI 'http://localhost:47275/api/telemetry/trial/login'.",
    "messageDetail": "No action was found on the controller 'LoginTelemetry' that matches the request."
}

If I change it to a [HttpGet] and put the appKey as a querystring, all is fine.

My app startup is very simple:

public void Configuration(IAppBuilder app)
    {
        log4net.Config.XmlConfigurator.Configure();
        HttpConfiguration httpConfig = new HttpConfiguration();
        httpConfig.MapHttpAttributeRoutes(); // <------ HERE

        FilterConfig.RegisterHttpFilters(httpConfig.Filters);
        LoggingConfig.RegisterHandlers(httpConfig.Services);

        ConfigureOAuth(app);
        ConfigureWebApi(httpConfig);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(httpConfig);
    }

Can anyone spot why POST requests aren't being found? Thanks


Solution

  • If I take string parameter out and replace it with a request object, it works...

    Instead of: public IHttpActionResult RecordLogin(string appKey)

    I create a request model class:

    public class PostLoginTelemetryRequest{ 
        public string appKey {get;set;}
    }
    

    Then alter the signature:

    public IHttpActionResult RecordLogin(PostLoginTelemetryRequest request)
    

    Everything works fine (why it can't take a regular string like MVC5 web dev, I don't know, but anyway...)

    (also note that I had tried this in every format from the client with the string method: form-url-encode, raw body, etc, so I'm fairly certain it wasn't a calling format issue).