Reputation: 4244
We are at the stage of deploying a project to our client's test server but unfortunately, we are receiving 405 errors every time our application tries to make calls to any of the Web Api methods we have made available.
My WebApi calls are defined as follows:
public class TourController : ApiController
{
[HttpPost]
public JsonCollection RequestTours([FromBody] DateRequest request){
// Implementation goes here
}
[HttpPost]
public GroupTour RequestTour([FromBody] int request){
// Implementation goes here
}
}
My WebApi routing is as follows:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
These calls work as defined when run locally though Visual Studio with no ammendments however, when we place them on our client's IIS test server we are consistently receiving 405 errors when calling the methods via AJAX (primary method) or via URL.
As suggested in other posts, we have tried defining the following in system.webServer:
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
We have also tried adding the following to no avail:
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/> <!-- add this -->
</modules>
<handlers>
<remove name="WebDAV" />
...
</handlers>
We are currently at a loss as we have tried most of the suggestions offered on similar Stack Overflow posts around the same subject. Any help or suggestions on this issue would be greatly appreciated!
N.B.
Just for the record, my calling method via Javascript / JQuery is doing the following:
function populateInstances(date) {
var $container = $('#id-tour_4');
$.ajax({
url: '/api/tour/requesttours',
type: 'POST',
data: { Date: date },
dataType: 'json',
success: function (data) {
var htmlstring = '';
$container.empty();
if (data.Results.length > 0) {
for (var i = 0; i < data.Results.length; i++) {
htmlstring += '<div class="book-title">' + data.Results[i].Name + '</div>';
htmlstring += '<div class="tour_select_list_div">';
htmlstring += '<ul class="tour_select_list">';
for (var j = 0; j < data.Results[i].Instances.length; j++) {
htmlstring += '<li><label for="id-tour_4_' + j + '"><input id="id-tour_4_' + j + '" type="radio" value="' + data.Results[i].Instances[j].TourId + '" name="BookTour.Instance" data-availability="' + data.Results[i].Instances[j].Availability + '" data-adultprice="' + data.Results[i].Instances[j].AdultPrice + '" data-childprice="' + data.Results[i].Instances[j].ChildPrice + '">';
htmlstring += data.Results[i].Instances[j].StartTime + ' - ' + data.Results[i].Instances[j].Title + '</label></li>';
}
htmlstring += '</ul>';
htmlstring += '</div>';
}
} else {
htmlstring += 'There are no tours departing on this date';
}
$container.append(htmlstring);
}
});
}
Upvotes: 4
Views: 3691
Reputation: 8818
Herewith, find a couple of options that might be of assistance in solving production problems
The check list:
[Route]
attribute[HttpPost] [Route("api/tour/requesttours")] public JsonCollection RequestTours([FromBody] DateRequest request)
You can try removing `[HttpPost]` when applying the `[Route]` attribute
Ensure that CORS is enabled
Check that you are using System.Web.Http
with the HttpPost
and not the Mvc namespace equivalent.
Upvotes: 1
Reputation: 6020
This could be a firewall or loadbalancer issue. If your client follows a strict least privilege policy you may have to ensure that the actual verb is allowed on a firewall/loadbalancer layer. Can you let your sysadmin check that?
Can you else confirm that the request reaches your service? Do you have any logging (in your application or at least the IIS logs that notice every request to your site) which confirms that the request comes through? Did you already put a web debugging proxy like fiddler in between the communication to get more detailed Infos?
Upvotes: 0
Reputation: 531
Ensure your client method performs the actual ACTION VERB your endpoint is expecting.
That is to say that is your endpoint is a POST, your client must POST to it and not PUT.
Please confirm.
Upvotes: 0