0

I can't seem to make an ajax call to my Web API controller. Either the URL isn't right (method not found) or I get a method not allowed error. This is my ajax call:

    $.ajax({
        url: 'server/InstallApp',
        type: 'POST',
        data: {server: serverAsJson, appWithGroup: appWithGroupAsJson},
        contentType: "application/json",
        success: InstallRequested
    });

That ajax call is being called from this URL:

http://serverName/PrestoWebApi/app/#/server/ApplicationServers%5E%5E8

These are the various URLs I've tried to use in the above ajax call, and the result:

url: 'server/InstallApp'

POST http://serverName/PrestoWebApi/app/server/InstallApp 404 (Not Found)

Notice that the # is missing. Not sure if that matters.

url: '#/server/InstallApp'

POST http://serverName/PrestoWebApi/app/ 405 (Method Not Allowed)

Not sure why the URL is truncated like that. Why Method Not Allowed when the URL doesn't even match the controller?

url: '/PrestoWebApi/app/#/server/InstallApp'

POST http://serverName/PrestoWebApi/app/ 405 (Method Not Allowed)

I'm not sure what to try. I've done this with other apps. I even tried putting webdav removal entries in my web.config.

This is my controller (note that I can call the Get method in my controller):

[EnableCors(origins: "http://serverName", headers: "*", methods: "*")]
public class ServerController : ApiController
{
    public ApplicationServer Get(string id)
    {
        // Get code here
    }

    [HttpPost]
    public void InstallApp(ApplicationServer server, ApplicationWithOverrideVariableGroup appWithGroup)
    {
        Debug.WriteLine("snuh");
    }

I'm at a loss. Any ideas on what to try?

Community
  • 1
  • 1
Bob Horn
  • 33,387
  • 34
  • 113
  • 219

2 Answers2

0

The URL for your ajax call should be, "HTTP://{{domainname}}.com/api/{{controller}}"

For example, "http://myapiproject.com/api/server"... unless you have your controller in a different directory than "Controllers."

Then, since you've set the HttpPost attribute on the "InstallApp" method of your controller, you just make sure that the 'type' setting in your ajax call is set to 'POST' and it should route.

Doing it this way, you won't be able to have two methods with the [HttpPost] attribute added to it.

Justin Russo
  • 2,214
  • 1
  • 22
  • 26
  • I tried specifying the URL, in the ajax call, like you said: `url: 'http://serverName/PrestoWebApi/app/#/server'`. That causes this: `POST http://serverName/PrestoWebApi/app/ 405 (Method Not Allowed)` – Bob Horn Dec 29 '14 at 19:02
  • In which case, your web api url should be http://serverName/PrestoWebApi/app/#/api/server – Justin Russo Dec 29 '14 at 19:07
  • But, since you're calling from the same domain, your URL in the ajax request should be '/api/server/' – Justin Russo Dec 29 '14 at 19:07
  • The first page that comes up on my site has this URL: `http://serverName/PrestoWebApi/app/#/apps` – Bob Horn Dec 29 '14 at 19:10
  • Okay, then the base URL on your .ajax call should be '/api/server' – Justin Russo Dec 29 '14 at 19:11
  • unless you've made changes in the web.config for the routes, or added any routes in the global.asax on application_start – Justin Russo Dec 29 '14 at 19:12
  • I've made no changes. I get a `not found` error when trying either of these: `'/PrestoWebApi/server'`, `'/api/server'`. – Bob Horn Dec 29 '14 at 19:17
  • I wonder if I need to add a route, like this: http://www.codeproject.com/Questions/626743/posting-object-to-web-api-though-Method-Not-Allowe – Bob Horn Dec 29 '14 at 19:22
  • Yeah, your route should be '/api/server.' You can also try '~/api/server' – Justin Russo Dec 29 '14 at 19:22
  • When you load your application, and it's on the index/home page, highlight the entire URL and compose an HTTP request in fiddler. Testing that way will let you determine if the problem is in your JQuery call, or your URL itself. – Justin Russo Dec 29 '14 at 19:23
  • To make it truly "restful" you need to be using your HTTP actions properly. The correct usage / routing in Web API to make it truly restful, is to set the Http action attribute on the method and then route to it by calling the controller and setting the action. – Justin Russo Dec 29 '14 at 19:26
  • You really should download fiddler and compose an HTTP Request using the full URL + '/api/server', and set the action to 'POST' to see if the problem is the javascript or your URL. – Justin Russo Dec 29 '14 at 19:28
  • In Fiddler, on the Composer tab, I get a 404 Not Found when using this URL: `http://serverName/PrestoWebApi/app/server` – Bob Horn Dec 29 '14 at 19:35
  • try 'http://serverName/PrestoWebApi/app/api/server' and 'http://serverName/PrestoWebApi/app/#/apps/api/server' – Justin Russo Dec 29 '14 at 20:39
  • 404 not found for both. Two things: I'm not sure why I would put "api" in the URL; I believe that's what "PrestoWebApi" is. Also, when I use # in the Fiddler URL, I get a pop-up where I have to enter numbers. Not sure what that's about. – Bob Horn Dec 29 '14 at 20:50
  • Go to your WebApiConfig.cs file in the "App_Start" directory, and you will see a default route. That route will be "api/controller/{id}' and 'id' will be optional. – Justin Russo Dec 29 '14 at 21:07
  • Can you take a screenshot of the popup you're getting from fiddler when you use the '#'? – Justin Russo Dec 29 '14 at 21:30
  • I just shared my screen with a friend of mine and he figured it out. He's going to post the answer here. Thank you for your suggestions. The issue is really that I'm still new to this. – Bob Horn Dec 29 '14 at 21:42
0

The # in your URL is used for client side logic, most likely routing, and is completely ignored in your WebAPI routes.

i.e. this URL:

http://serverName/PrestoWebApi/app/#/server/ApplicationServers%5E%5E8

Is interpreted as this on the server:

http://serverName/PrestoWebApi/app/

The second issue I see is that, unless you specifically changed this in your WebApiConfig, your WebAPI methods do not reside at /app, rather /api (or possibly /server in your case). You could change your ajax call to:

$.ajax({
    url: '/PrestoWebApi/server/InstallApp', // or /PrestoWebApi/api/server/InstallApp
    type: 'POST',
    data: {server: serverAsJson, appWithGroup: appWithGroupAsJson},
    contentType: "application/json",
    success: InstallRequested
});

You can see exactly what the URL should look like by going to the WebAPI welcome page (probably http://serverName/PrestoWebApi/api) and looking at the Help page by clicking Api from the navigation bar.

Tom
  • 7,640
  • 1
  • 23
  • 47
  • Basically you need to remove the '/InstallApp' portion of the URL for your app to be considered truly restful to Level 2 of the Richardson Maturity Model. The only other concern is HATEOS, which is implemented in your app design pattern. – Justin Russo Dec 29 '14 at 22:40
  • Whether his app is RESTful or not is another question; this answer is the cause and solution to the problem. Not sure why the down vote @JustinRusso – Tom Dec 29 '14 at 23:05
  • No, it IS also part of the answer. He had the "[HttpPost]" attribute assigned to the method, which means the ACTUAL URL should not include the action. – Justin Russo Dec 30 '14 at 00:14
  • 1
    Oh, right. I guess I had some extra information, but he had added an extra route to accommodate the "action" of a URL – Tom Dec 30 '14 at 01:07