Razor Pages PageModel binding for GET with AJAX - 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) {
}
});

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.

Passing multiple ajax parameters to mvc controller

I can pass a serialized form to a mvc controller no problems with code below and all is populated
$("#btnExecuteJob").on("click", function (e) {
var frmForm1 = $("#form1").serialize();
$.ajax({
cache: false,
url: "/mvcController/executeJob",
dataType: 'json',
type: 'POST',
data: frmForm1,
success: function (resp) {},
error: function (resp) {}
});
});
Controller
[HttpPost]
public ActionResult executeJob(runDetails jobDetails)
{
//
// Process
//
return View();
}
I have added a second form to my view and now want to pass both to the controller so I tried
$("#btnExecuteJob").on("click", function (e) {
var frmForm1 = $("#form1").serialize();
var frmForm2 = $("#form2").serialize();
$.ajax({
cache: false,
url: "/jobScheduler/executeJob",
dataType: 'json',
type: 'POST',
data: {
jobDetails: frmForm1,
jobParameters: frmForm2
},
success: function (resp) {},
error: function (resp) {}
});
});
Controller
public ActionResult executeJob(runDetails jobDetails, runParams jobParameters)
{
//
// Process
//
return View();
}
and neither jobDetails or jobParams is populated, both work individually as first example
and all details are populated, any help much appreciated,
both forms really need to be separate in the controller

MVC Ajax Post error

I am getting error while I post Ajax request to controller method. In controller method I need to pass Model class object.
But it gives me 500 Internal server error.
Can anybody help me to make it correct?
Mu code is as per below:
jQuery:
var request = $("#frmHost").serialize();
$.ajax({
url: "/Host/HostItemDetails/" ,
type: "POST",
datatype: 'json',
contentType : "application/json",
data: request,
success: function (data) {
if (data == '1111') {
///Success code here
}
else if (data != '') {
jAlert(data);
}
}
});
Controller Method :
[HttpPost]
public JsonResult HostItemDetails(ClsHost objHost)
{
//Code here
return Json("1111");
}
Nirav Try this,
Parse the serialized data as a JSON object and later stringify that while posting using JSON.stringify().
$("#Button").click(function () {
var data = $("#frmHost").serialize().split("&");
var request = {};
for (var key in data) {
request[data[key].split("=")[0]] = data[key].split("=")[1];
}
$.ajax({
url: "/Home/HostItemDetails/",
type: "POST",
datatype: 'json',
contentType: "application/json",
data: JSON.stringify(request),
success: function (data) {
if (data == '1111') {
///Success code here
}
else if (data != '') {
jAlert(data);
}
}
});
});
I ran the same code that you are running.
To test the code I did the following changes. I took a button, and on click event I am sending the post back to the controller.
the '[HttpPost]' attribute is fine too.
Can you make one thing sure, that the frmHost data matches to the class ClsHost,but still that shouldn't cause the server error, the error will be different.
$(document).ready(function () {
$("#clickMe").click(function () {
var request = '{"Users":[{"Name":"user999","Value":"test"},{"Name":"test2","Value":"test"}]}';
$.ajax({
url: "/Home/HostItemDetails/",
type: "POST",
datatype: 'json',
contentType: "application/json",
data: request,
success: function (data) {
if (data == '1111') {
///Success code here
}
else if (data != '') {
jAlert(data);
}
}
});
});
});
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult HostItemDetails(ClsHost objHost)
{
//Code here
return Json("111", JsonRequestBehavior.AllowGet);
}
It is solved by removing same property name in Model class. It is mistakenly added by me twice.

When i call ajax there url wrong why?

I have a one Edit.cshtml page and there is 1 partial template call. in that template I make an ajax call and my controller is home and action name is savedata
ajax function
$.ajax({
url: "CountryZone/SaveData",
type: 'POST',
data: { data: selectedID, id: id },
dataType: "html",
success: function (result) {
alert("Success");
},
error: function (result) {
data.str = null;
alert("Error");
},
});
controller:--
public ActionResult Savedata(string data, int CountryZoneId)
{
return null;
}
now when my ajax call is going
there is url wrong :--- url is Home/edit/Home/Savedata instead of this there is only Home/SaveData
It's a bad idea to hardcode urls in MVC application.
Change this line:
url: "CountryZone/SaveData",
To this:
url: "/CountryZone/SaveData",
I suggest at least using Url.Action in the view and storing it in the js variable.
Use standard MVC code as below:
url: '#Url.Action("SaveData","CountryZone")',
Full Code
$.ajax({
url: '#Url.Action("SaveData","CountryZone")',
type: 'POST',
data: { data: selectedID, CountryZoneId: id },
dataType: "html",
success: function (result) {
alert("Success");
},
error: function (result) {
data.str = null;
alert("Error");
},
});
[HttpPost]
public ActionResult Savedata(string data, int CountryZoneId)
{
return null;
}

can't get to web api controller action with jquery ajax post

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'); }
});

Resources