I am new to MVC and Ajax, but have good working knowledge and experience with C#.
As a test, I have created an ApiController with 4 methods, 2 using GET and 2 using POST.
All 4 methods work perfectly fine with @Ajax.ActionLink, but (to my best knowledge) equivalent $.ajax call fails POST (but passes GET).
Here is my ApiController:
public class ValuesController : ApiController { [HttpGet] // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } [HttpGet] // GET api/values/5 public string Get(int id) { return $"id={id}, ~id={~id}"; } [HttpPost] // POST api/values public string PostData(string value="123") { var x = Request; return new string(value.Reverse().ToArray()); } [HttpPost] // POST api/values public JsonResult<object> PostData(string value, int i) { return Json((object)new { s=new string(value.Reverse().ToArray()), i }); } } And the corresponding calls from .cshtml file:
@Ajax.ActionLink("Click me for Get()", "Get", "api/Values", null, new AjaxOptions() { HttpMethod = "GET", OnSuccess = "res0", OnFailure = "fail0", UpdateTargetId = "status0" }) <script language="javascript"> function res0(res) { $('#status00')[0].innerText = "Result: " + res; } function fail0(a, b, c) { $('#status000')[0].innerText = "Error\n" + b + '\n' + c; } </script> <form action="" id="form0"> <input type="submit" /> </form> <div id="status0"></div> <div id="status00"></div> <div id="status000"></div> @Ajax.ActionLink("Click me for Get(5)", "Get", "api/Values", new { id = 5 }, new AjaxOptions() { HttpMethod = "GET", OnSuccess = "res1", OnFailure = "fail1", UpdateTargetId = "status1" }) <script language="javascript"> function res1(res) { $('#status11')[0].innerText = "Result: " + res; } function fail1(a, b, c) { $('#status111')[0].innerText = "Error\n" + b + '\n' + c; } </script> <form action="" id="form1"> <input type="submit" /> </form> <div id="status1"></div> <div id="status11"></div> <div id="status111"></div> @Ajax.ActionLink("Click me for PostData('Hello')", "PostData", "api/Values", new { value = "Hello" }, new AjaxOptions() { HttpMethod = "POST", OnSuccess = "res2", OnFailure = "fail2", UpdateTargetId = "status2" }) <script language="javascript"> function res2(res) { $('#status22')[0].innerText = "Result: " + res; } function fail2(a, b, c) { $('#status222')[0].innerText = "Error\n" + b + '\n' + c; } </script> <form action="" id="form2"> <input type="submit" /> </form> <div id="status2"></div> <div id="status22"></div> <div id="status222"></div> @Ajax.ActionLink("Click me for PostData(\"Hello\", 3)", "PostData", "api/Values", new { value = "Hello", i = 3 }, new AjaxOptions() { HttpMethod = "POST", OnSuccess = "res3", OnFailure = "fail3", UpdateTargetId = "status3" }) <script language="javascript"> function res3(res) { $('#status33')[0].innerText = "Result: " + JSON.stringify(res); } function fail3(a, b, c) { $('#status333')[0].innerText = "Error\n" + b + '\n' + c; } </script> <form action="" id="form3"> <input type="submit" /> </form> <div id="status3"></div> <div id="status33"></div> <div id="status333"></div> <script language="javascript"> document.getElementById('form0').onsubmit = function (e) { e.preventDefault(); form0_submit(); }; document.getElementById('form1').onsubmit = function (e) { e.preventDefault(); form1_submit(); }; document.getElementById('form2').onsubmit = function (e) { e.preventDefault(); form2_submit(); }; document.getElementById('form3').onsubmit = function (e) { e.preventDefault(); form3_submit(); }; function form0_submit() { $.ajax({ type: 'GET', url: '/api/Values/Get', success: function (res) { $('#status0')[0].innerText = res; }, error: function (jqXHR, tStatus, errThrown) { $('#status00')[0].innerText = tStatus; $('#status000')[0].innerText = errThrown; } }); } function form1_submit() { $.ajax({ type: 'GET', url: '/api/Values/Get', data: {id:@DateTime.Now.TimeOfDay.Seconds}, success: function (res) { $('#status1')[0].innerText = res; }, error: function (jqXHR, tStatus, errThrown) { $('#status11')[0].innerText = tStatus; $('#status111')[0].innerText = errThrown; } }); } function form2_submit() { $.ajax({ type: 'POST', url: '/api/Values/PostData', data: JSON.stringify({ value: "Test string" }), contentType: 'application/json; charset=UTF-8', dataType: 'json', success: function (res) { $('#status2')[0].innerText = res; }, error: function (jqXHR, tStatus, errThrown) { $('#status22')[0].innerText = tStatus; $('#status222')[0].innerText = errThrown; } }); } function form3_submit() { // not implemented yet, need to get form2_submit() working } </script> I used to get a 404 - Not found error until in public string PostData(string value="123") I made value an optional parameter. Now the function is called with the default "123" value, not what I pass it. In form2_submit() I tried different combinations for the data parameter.
Analysing the response using the Chrome developer tools (right-click->Inspect, then Network tab), I can see that the ActionLink sends the parameters as Query String Parameters, while the $.ajax call does it as Request Payload or Form Data depending on exactly what I pass to data parameter. In both cases, the parameter name/value pair is correct, but the C# ApiController seems to ignore that value (I have tried [FromBody] attribute as well).
I've checked other posts here and on other sites, but cannot figure out why the data is being transmitted differently
Edit:
As requested, the output of Get-Package:
PM> Get-Package Id Versions ProjectName -- -------- ----------- Antlr {3.4.1.9004} WebApplication1 bootstrap {3.0.0} WebApplication1 jQuery {1.10.2} WebApplication1 Microsoft.ApplicationInsights {2.2.0} WebApplication1 Microsoft.ApplicationInsights.Ag... {2.0.6} WebApplication1 Microsoft.ApplicationInsights.De... {2.2.0} WebApplication1 Microsoft.ApplicationInsights.Pe... {2.2.0} WebApplication1 Microsoft.ApplicationInsights.Web {2.2.0} WebApplication1 Microsoft.ApplicationInsights.Wi... {2.2.0} WebApplication1 Microsoft.ApplicationInsights.Wi... {2.2.0} WebApplication1 Microsoft.AspNet.Mvc {5.2.3} WebApplication1 Microsoft.AspNet.Razor {3.2.3} WebApplication1 Microsoft.AspNet.Web.Optimization {1.1.3} WebApplication1 Microsoft.AspNet.WebApi {5.2.3} WebApplication1 Microsoft.AspNet.WebApi.Client {5.2.3} WebApplication1 Microsoft.AspNet.WebApi.Core {5.2.3} WebApplication1 Microsoft.AspNet.WebApi.HelpPage {5.2.3} WebApplication1 Microsoft.AspNet.WebApi.WebHost {5.2.3} WebApplication1 Microsoft.AspNet.WebPages {3.2.3} WebApplication1 Microsoft.CodeDom.Providers.DotN... {1.0.8} WebApplication1 Microsoft.jQuery.Unobtrusive.Ajax {3.2.5} WebApplication1 Microsoft.Net.Compilers {2.4.0} WebApplication1 Microsoft.Web.Infrastructure {1.0.0.0} WebApplication1 Modernizr {2.6.2} WebApplication1 Newtonsoft.Json {6.0.4} WebApplication1 Respond {1.2.0} WebApplication1 WebGrease {1.5.2} WebApplication1 PM>
Get-Packagefrom your NuGet consoleActionNameattribute, so I doubtGet(as in the action name) is an issue. I could try if you insist though, but again, it's POST not working, GET is fine...