I've been successfully using this method to GET REST data:
private JArray GetRESTData(string uri)
{
try
{
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
return JsonConvert.DeserializeObject<JArray>(s);
}
catch // This method crashes if only one json "record" is found - try this:
{
try
{
MessageBox.Show(GetScalarVal(uri));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return null;
}
Between the webRequest and webResponse assignments, I added this:
if (uri.Contains("Post"))
{
webRequest.Method = "POST";
}
...and called it with this URI:
http://localhost:28642/api/Departments/PostDepartment/42/76TrombonesLedTheZeppelin
Although I have a Post method that corresponds to it:
Controller
[Route("api/Departments/PostDepartment/{accountid}/{name}/{dbContext=03}")]
public void PostDepartment(string accountid, string name, string dbContext)
{
_deptsRepository.PostDepartment(accountid, name, dbContext);
}
Repository
public Department PostDepartment(string accountid, string name, string dbContext)
{
int maxId = departments.Max(d => d.Id);
// Add to the in-memory generic list:
var dept = new Department {Id = maxId + 1, AccountId = accountid, Name = name};
departments.Add(dept);
// Add to the "database":
AddRecordToMSAccess(dept.AccountId, dept.Name, dbContext);
return dept;
}
...it fails with, "The remote server returned an error: (405) Method Not Allowed."
Why is it not allowed?
Based on what I found here: http://blog.codelab.co.nz/2013/04/29/405-method-not-allowed-using-asp-net-web-api/, I added this to Web.Config:
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT"
type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
...so that it went from this:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*"
type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer></configuration>
...to this:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT"
type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer></configuration>
....but it made no diff.
It doesn't even make it to the call in the Controller:
[HttpPost]
[System.Web.Http.Route("api/Departments/PostDepartment/{accountid}/{name}/{dbContext=03}")]
public void PostDepartment(string accountid, string name, string dbContext)
{
_deptsRepository.PostDepartment(accountid, name, dbContext);
}
I have a breakpoint inside it that's not reached...???
VirtualBlackFox's last comment was the one that did the trick. I just changed my "is it a post?" in my client code to the following:
if (uri.Contains("Post"))
{
webRequest.Method = "POST";
webRequest.ContentLength = 0; // <-- This line is all I added
}
...and now it works.
I don't do Asp.Net but i'll guess that you need to specify the HttpPost
attribute as can be seen in Attribute Routing / HTTP Methods documentation :
[HttpPost]
[Route("api/Departments/PostDepartment/{accountid}/{name}/{dbContext=03}")]
public void PostDepartment(string accountid, string name, string dbContext)
{
_deptsRepository.PostDepartment(accountid, name, dbContext);
}
Small sample that work on my PC :
TestController.cs:
using System.Web.Http;
namespace WebApplication2.Controllers
{
public class TestController : ApiController
{
[HttpPost]
[Route("api/Departments/PostDepartment/{accountid}/{name}/{dbContext=03}")]
public string PostDepartment(string accountid, string name, string dbContext)
{
return accountid + name + dbContext;
}
}
}
Test.html :
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
$(function () {
$.ajax("api/Departments/PostDepartment/accountid/name/dbContext", {
type: 'POST', success: function (data) {
$('#dest').text(data);
}
});
});
</script>
</head>
<body>
<div id="dest"></div>
</body>
</html>
Sample program to call the service in C# :
namespace ConsoleApplication1
{
using System;
using System.IO;
using System.Net;
using Newtonsoft.Json;
class Program
{
static void Main()
{
Console.WriteLine(GetRestData(@"http://localhost:52833//api/Departments/PostDepartment/42/76TrombonesLedTheZeppelin"));
Console.ReadLine();
}
private static dynamic GetRestData(string uri)
{
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Method = "POST";
webRequest.ContentLength = 0;
var webResponse = (HttpWebResponse)webRequest.GetResponse();
var reader = new StreamReader(webResponse.GetResponseStream());
string s = reader.ReadToEnd();
return JsonConvert.DeserializeObject<dynamic>(s);
}
}
}