can't get to web api controller action with jquery ajax post - asp.net-web-api

I'm trying to create my first REST application with the web api in mvc4. I have a controller set up with the HttpPost verb but for some reason when I click the link to post the xml string to the controller I get an error - "{"Message":"No HTTP resource was found that matches the request URI '/api/Apply/ApplyToJob'.","MessageDetail":"No action was found on the controller 'Apply' that matches the request."}" Any ideas what I might be doing wrong? Here's the view page...
Post Data
<script type="text/javascript">
window.onload = function () {
$("#lnkPost").on("click", function () {
$.get("/TestResponse.xml", function (d) {
$.ajax({
//contentType: "text/xml",
//dataType: "xml",
type: "post",
url: "/api/Apply/ApplyToJob",
data: {
"strXml": (new XMLSerializer()).serializeToString(d)
},
success: function () { console.log('success'); }
});
});
});
};
</script>
and here's the controller.
public class ApplyController : ApiController
{
[HttpPost]
[ActionName("ApplyToJob")]
public string ApplyToJob(string strXml)
{
return "success";
}
}

Modify your action's parameter like below:
public string ApplyToJob([FromBody]string strXml)
This is because without this FromBody attribute, the string parameter is expected to come from the Uri. Since you do not have it in the Uri the action selection is failing.
Also, looking at your client code, shouldn't you set the appropriate content type header in your request?
Edited:
You can modify your javascript to like below and see if it works:
$.ajax({ contentType: "text/xml",
dataType: "xml",
type: "post",
url: "/api/values",
data: "your raw xml data here",
success: function () { console.log('success'); }
});

Related

Unable to 'call' controller action from ajax post

I'm using net.core for the first time today and I'm trying to call an action method from an ajax call:
My Ajax call (from a normal HTML page)
$("#contactMap").click(function (e) {
e.preventDefault();
var url = "/MapObjects/mapContact";
//I've tried MapObjectsController & '#Url.Action("mapContact", 'MapObjects")'; But to no avail
$.ajax({
url: url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
cache: false,
success: function (result) {
alert("success");
}
});
});
And in my controller:
namespace myName.Controllers
{
public class MapObjectsController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public JsonResult mapContact()
{
Account account = new Account();
return Json(account);
}
}
}
The 'account' is just a normal model (obvs empty in this case). All I receive is a 404 error in the console though.
As mentioned this is the 1st time I've .net Core (this is code I've written loads of times in 'normal' MVC projects) so it's possible that I'm missing something really obvious.
Thanks,
C
The first, try to call the #Url.Action() explicitly in the Ajax call :
$("#contactMap").click(function (e) {
e.preventDefault();
$.ajax({
url: '#Url.Action("mapContact", "MapObjects")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
cache: false,
success: function (result) {
alert("success");
}
});
});
The second, check your routing rules.

Razor Pages PageModel binding for GET with AJAX

I am having trouble getting binding to work with a specific set of circumstances. I am using Razor Pages with ASP.NET Core 3.1 to act like a controller for servicing AJAX calls. I have already added the anti-forgery token to the Startup.cs:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
My AJAX calls include the anti-forgery in the calls and look like:
function getTankConfig(tankId) {
var json = { id: tankId };
$.ajax({
cache: false,
type: "GET",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
url: "/Tank/Config",
contentType: "application/json",
dataType: "json",
data: JSON.stringify(json),
success: getTankConfigSuccess
});
}
function getTankConfigSuccess(data) {
if (data !== null) {
// do stuff with data
}
}
I have tried about every combination of binding technique. Using the parameter normally, adding [FromBody], adding a public property and giving it the [BindProperty] attribute, using [BindProperty(SupportsGet = true)]. It seems like it was so simple when using a controller to do this, but I am not finding the magic for making it work with Razor Pages and PageModels.
Here is the simplified version of my PageModel class:
public class TankConfigModel : PageModel
{
public JsonResult OnGet(int id)
{
TankConfigViewModel config = new TankConfigViewModel();
config.Id = id;
return new JsonResult(config);
}
}
Any help or guidance would be greatly appreciated. Thanks.
You have to add this to your razor page
#page "{id}"
and fix ajax
$.ajax({
type: "GET",
url: "/Tank/Config/"+tankId,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (result) {
getTankConfigSuccess(result)
},
error: function (jqXHR) {
}
});

Ajax and ASP.NET MVC- Get page URL, not the controller/action URL

I have an Ajax method that calls an MVC action from a controller class.
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "/ajax/Updates/Message",
dataType: "json",
success: function (response) {
//data variable has been declared already
data = response;
},
complete: function () {
if (data !== "") {
$('#div1').text(window.location.path);
$('#div2').text(data);
}
},
});
[HttpGet]
public async Task < ActionResult > Message()
{
string d = "test string";
return Json(d, JsonRequestBehavior.AllowGet);
}
The 'url' within the Ajax method is the call to the action method.
What to do if I want to return the actual page URL in Ajax Response, not the controller/action url?
So this controller does not have a view or anything associated with it, it is more like a helper class. When I am using ajax in any of the other pages, it is not returning the URL path of that specific page (via 'window.location.path) e.g. /Accounts/Summary , rather it is returning Updates/Message (in reference to the controller and action)
The web is stateless, when you call Updates/Message with ajax, it doesn't know it's for page Accounts/Summary. You'll have to pass this as parameter (post or get) or you could try Request.UrlReferrer which should contain the url of the page that called the request.
I hope this will help you try this code:
ajax code
$.ajax({
type: 'GET',
url: '#Url.action("Message","Updates")', // url.action(ActionName,ControllerName)
success: function (data) {
window.location = data;
},
error: function (xhr) { // if error occured
alert("Error occured.please try again");
}
dataType: 'json'
});
actionresult :
[HttpGet]
public async Task<ActionResult> Message()
{
string d = "http://www.google.com";
return Json(d, JsonRequestBehavior.AllowGet);
}

ASP.NET & Ajax - How to pass value from ajax to action?

I have a few checkboxes on my page. I have some jquery in place to ensure that only one checkbox is checked at a time. I have assigned a specific value to each checkbox. The below ajax finds the checkbox that is checked and I'm grabbing the value associated to it. How do I pass that value to my action?
AJAX
$("input:checkbox").click(function () {
var PaymentID = document.querySelector('#chkBox:checked').value;
alert(PaymentID); // for test
$.ajax({
type: "POST",
dataType: "json",
data: PaymentID,
contentType: "application/json; charset=utf-8",
url: "#Url.Action("MyAction", "Home")",
success: function () {
return PaymentID; // Failed attempt at passing data.
}
})
})
Action:
[HttpPost]
public ActionResult MyAction(string PaymentID)
{
// Magic
}
Please keep in mind i am fairly new to ajax. Thx guys.
You can pass a javascript object with name PaymentID ( same name as your action method parameter)
data: { PaymentID: PaymentID },
You do not need to specify contentType as you are sending a simply object. Also you do not necessarily need to specify dataType for your ajax call to send the data.
This should work.
var PaymentID = "some value";
$.ajax({
type: "POST",
data: { PaymentID: PaymentID },
url: "#Url.Action("MyAction", "Home")",
success: function (response) {
console.log('response', response);
}
});
Or you can use the $.post method.
$.post("#Url.Action("MyAction", "Home")",{ PaymentID: PaymentID }, function(response) {
console.log('response', response);
});

Rendering a simple ASP.NET MVC PartialView using JQuery Ajax Post call

I have the following code in my MVC controller:
[HttpPost]
public PartialViewResult GetPartialDiv(int id /* drop down value */)
{
PartyInvites.Models.GuestResponse guestResponse = new PartyInvites.Models.GuestResponse();
guestResponse.Name = "this was generated from this ddl id:";
return PartialView("MyPartialView", guestResponse);
}
Then this in my javascript at the top of my view:
$(document).ready(function () {
$(".SelectedCustomer").change( function (event) {
$.ajax({
url: "#Url.Action("GetPartialDiv/")" + $(this).val(),
data: { id : $(this).val() /* add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
}
});
});
function SetData(data)
{
$("#divPartialView").html( data ); // HTML DOM replace
}
});
Then finally my html:
<div id="divPartialView">
#Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>
Essentially when a my dropdown tag (which has a class called SelectedCustomer) has an onchange fired it should fire the post call. Which it does and I can debug into my controller and it even goes back successfully passes back the PartialViewResult but then the success SetData() function doesnt get called and instead I get a 500 internal server error as below on Google CHromes console:
POST http:// localhost:45108/Home/GetPartialDiv/1 500 (Internal Server
Error) jquery-1.9.1.min.js:5 b.ajaxTransport.send
jquery-1.9.1.min.js:5 b.extend.ajax jquery-1.9.1.min.js:5 (anonymous
function) 5:25 b.event.dispatch jquery-1.9.1.min.js:3
b.event.add.v.handle jquery-1.9.1.min.js:3
Any ideas what I'm doing wrong? I've googled this one to death!
this line is not true: url: "#Url.Action("GetPartialDiv/")" + $(this).val(),
$.ajax data attribute is already included route value. So just define url in url attribute. write route value in data attribute.
$(".SelectedCustomer").change( function (event) {
$.ajax({
url: '#Url.Action("GetPartialDiv", "Home")',
data: { id : $(this).val() /* add other additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data, textStatus, XMLHttpRequest) {
SetData(data);
}
});
});

Resources