4
votes

I'm receiving a 405 error with a POST request using $http.post. What's weird is that I'm using $http.post in another area of my application and it works just fine.

I'm using AngularJS for client side, and Web API for server side. I've posted all relevant information (apart from my web.config) that I can think of. Is there something very obvious I'm missing here?


code below does not work (throws 405)

Here's the api controller method that I'm trying to hit:

    public async Task<IHttpActionResult> LinkLogin(string provider)
    {
        Account user = await _repo.FindByNameAsync(User.Identity.Name);

        if (user == null)
        {
            return BadRequest("User does not exist!");
        }

        return new ChallengeResult(provider, null, "auth/Manage/LinkLoginCallback", user.Id);
    }

Here's how I'm trying to hit it on the client side:

var _linkLogin = function (provider) {
    $http.post(serviceBase + 'auth/Manage/LinkLogin', provider).then(function (response) {
        return response;
    });
};

CODE BELOW IS CODE THAT WORKS

Api controller function that works:

    // POST auth/Authorization/Register
    [AllowAnonymous]
    [Route("Register")]
    public async Task<IHttpActionResult> Register(UserModel userModel)
    {
         if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

         IdentityResult result = await _repo.RegisterUser(userModel);

         IHttpActionResult errorResult = GetErrorResult(result);

         if (errorResult != null)
         {
             return errorResult;
         }

         return Ok();
    }

Calling it from the client side:

var _saveRegistration = function (registration) {

    _logOut();

    return $http.post(serviceBase + 'auth/Authorization/register', registration).then(function (response) {
        return response;
    });

};

Here is my web api configuration:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes  
        config.MapHttpAttributeRoutes();

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

        config.Routes.MapODataServiceRoute("ODataRoute", "api", GenerateEdmModel());

        var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
        jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }

    private static IEdmModel GenerateEdmModel()
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); 

        return builder.GetEdmModel();
    }
}

Now I have tried a number of different solutions posted on the web to no avail, the following are links to things I have tried:

Web api not supporting POST method

Web API Put Request generates an Http 405 Method Not Allowed error

http://blog.dontpaniclabs.com/post/2013/01/23/That-Pesky-Requested-Resource-Does-Not-Support-HTTP-Method-POST-Error-When-Using-MVC-Web-API

1
Do you have a Route attribute on LinkLogin? [Route("LinkLogin")]Brad Barber
When I add that I get the following error: 'No action was found on the controller 'Manage' that matches the request.Ryan Duffing
Can you confirm us that your function " public async Task<IHttpActionResult> LinkLogin(string provider)" is in a controller named "Manage" ?Aliz
Do you need to add the [HttpPost] attribute to LinkLogin as well?Vlad274
How is the provider value set? I think your method needs to have [FromBody] atttribute for the provider parameter public async Task<IHttpActionResult> LinkLogin([FromBody]string provider)Wayne Ellery

1 Answers

2
votes

I hate answering my own question. If anyone else runs into this issue it's because you're trying to send a simple string value to a web api controller.

I used this solution with success: http://jasonwatmore.com/post/2014/04/18/Post-a-simple-string-value-from-AngularJS-to-NET-Web-API.aspx

If the link is dead, you simple wrap the string value in double quotes in your POST request like so:

$http.post(Config.apiUrl + '/processfile', '"' + fileName + '"');