I am trying to make an ajax sending data in JSON from a partial view. I get a System.ArgumentException: Invalid JSON primitive: undefined.
When I evaluate the object in a browser data contains an int and two strings. Can anyone tell me what I am doing wrong?
Partial View
#model FTD.Models.FTDAccountExtended
#using (Html.BeginForm()) {
<fieldset>
<legend>Update Policy Number</legend>
#Html.HiddenFor(m => m.account.ftd_accountsid)
#Html.HiddenFor(m => m.OldPolicyNumber)
#Html.TextBoxFor(m => m.account.ftd_policyno)
<input type="button" value="update" id="update" />
</fieldset>
}
<script type="text/javascript">
$(document).ready(function () {
$("#update").click(function () {
var myUrl = '#Url.Content("~/")' + '/Maintenance/UpdatePolicyNumber';
var data = [{ 'ClientNumber': parseInt($("#account_ftd_accountsid").val()), 'OldPolicyNumber': $("#OldPolicyNumber").val(), 'NewPolicyNumber': $("#account_ftd_policyno").val()}];
$.ajax({
url: myUrl,
type: 'POST',
data: data,
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data.message);
},
error: function (errMsg) {
alert("Error", errMsg);
}
});
});
});
The controller method is
public ActionResult UpdatePolicyNumber(int ClientNumber, string OldPolicyNumber, string NewPolicyNumber)
{
var message = string.Format("UpdatePolicyNumber CN:{0} OP:{1} NP:{2}", ClientNumber, OldPolicyNumber, NewPolicyNumber);
if (_log.IsDebugEnabled)
_log.Debug(message);
if (!string.IsNullOrEmpty(NewPolicyNumber) && ClientNumber > 0)
{
_entities = new CloseFTD_Entities();
_entities.UpdatePolicyNumber(ClientNumber, OldPolicyNumber, NewPolicyNumber, User.Identity.Name);
}
return Json
(
new
{
message = message
},
JsonRequestBehavior.AllowGet
);
}
I would just try posting the the data as a java script object (as Marc mentioned above)
and remove the content type attribute.
success: function (data) {
alert(data.success);
},
shouldn't this be
success: function (data) {
alert(data.message);
},
Your problem is here
var data = [{ 'ClientNumber': parseInt($("#account_ftd_accountsid").val()), 'OldPolicyNumber': $("#OldPolicyNumber").val(), 'NewPolicyNumber': $("#account_ftd_policyno").val()}];
You are building an array - but your controller excepts the direct values, so just remove the [] brackets:
var data = { 'ClientNumber': parseInt($("#account_ftd_accountsid").val()), 'OldPolicyNumber': $("#OldPolicyNumber").val(), 'NewPolicyNumber': $("#account_ftd_policyno").val()};
That should work.
Related
Not for the first time, I'm seeing that my Razor Pages seem to be handling GET/POST actions strangely when posting with ajax.
The latest example looks like this:
#inject IAntiforgery antiForgery
#{
ViewData["Title"] = "Disclaimers";
Layout = "~/Pages/Shared/_Blade.cshtml";
var token = antiForgery.GetAndStoreTokens(HttpContext).RequestToken;
}
$(".save-button").on("click", function(e) {
e.preventDefault;
const body = document.querySelector(".editor").innerText;
let disclaimer = {
clientid: parseInt($("#Disclaimer_Client_Id").val()),
description: $("#Disclaimer_Description").val(),
type: $("#Disclaimer_Type").val(),
markup: body
};
$.ajax({
method: "GET",
url: "./Create?handler=Create",
headers: {
"RequestValidationToken": "#token"
},
data: disclaimer,
dataType: "application/json",
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
});
I've done it this way because I'm using quilljs which employs a div for it's rich text editor. I can't use asp-for bindings on the div to bind it to the model.
public async Task<IActionResult> OnGetCreate(CreateDisclaimerViewmodel model)
{
var disclaimer = new Disclaimer
{
Created = DateTime.Now,
CreatedBy = User.Identity.Name,
Description = model.Description,
Markup = model.Markup,
Type = model.Type
};
if (model.ClientId > 0)
{
disclaimer.Client = await context.Clients.FindAsync(model.ClientId);
}
context.Disclaimers.Add(disclaimer);
await context.SaveChangesAsync();
return Redirect("/Disclaimers/Index");
}
With the code set up as using a GET method, it all works, but in this case, it should clearly be a POST.
Change it to a POST however and an empty response is returned with HTTP 400...
$(".save-button").on("click", function(e) {
e.preventDefault;
const body = document.querySelector(".editor").innerText;
let disclaimer = {
clientid: parseInt($("#Disclaimer_Client_Id").val()),
description: $("#Disclaimer_Description").val(),
type: $("#Disclaimer_Type").val(),
markup: body
};
$.ajax({
// Only the method changes here, everything else is above.
method: "POST",
url: "./Create?handler=Create",
headers: {
"RequestValidationToken": "#token"
},
data: disclaimer,
dataType: "application/json",
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
}
});
});
And the page model:
// Only the method changes (OnGetCreate becomes OnPostCreate).
public async Task<IActionResult> OnPostCreate(CreateDisclaimerViewmodel model)
{
var disclaimer = new Disclaimer
{
Created = DateTime.Now,
CreatedBy = User.Identity.Name,
Description = model.Description,
Markup = model.Markup,
Type = model.Type
};
if (model.ClientId > 0)
{
disclaimer.Client = await context.Clients.FindAsync(model.ClientId);
}
context.Disclaimers.Add(disclaimer);
await context.SaveChangesAsync();
return Redirect("/Disclaimers/Index");
}
This clearly should be a POST request but it simply won't work when using POST.
So what am I missing or misunderstanding? And since the solution can't be to use GET, what's the solution?
Shorten answer:
You use the wrong header name, it should be RequestVerificationToken:
headers: {
"RequestVerificationToken": "#token"
},
You are getting a 400 (Bad Request) response because the framework expects the RequestVerificationToken as part of the posted request. Be sure you have send it correctly.
Common way use ajax post in Razor Pages
Be sure your form tag does not have action attribute and then it will dynamically add a hidden input for token (You can F12 in browser to check whether your html contains input named __RequestVerificationToken, Ctrl+F and search for __RequestVerificationToken):
<form method="post">
//other elements...
<input class="save-button" type="button" value="CHANGE"/>
</form>
#section Scripts
{
<script>
$(".save-button").on("click", function(e) {
e.preventDefault;
//...
$.ajax({
// Only the method changes here, everything else is above.
method: "POST",
url: "?handler=Location",
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
data: disclaimer,
dataType: "application/json",
//...
});
});
</script>
}
Otherwise, you will need manually add it by using #Html.AntiForgeryToken() in the form:
<form method="post">
//other elements...
#Html.AntiForgeryToken()
<input class="save-button" type="button" value="CHANGE"/>
</form>
I am trying as the title says to return a Json message from the Controller to the View after it validates.
I have made a breakpoint, and I know that the code works from Controller side, and that my JavaScript calls with success the ActionResult now. How do I display that message in the View?
There are two buttons, stamp in and stamp out. If the user stamps in twice, it should get a message, same with stamp out. I have two ActionResults who are indentical except some message and string changes.
Controller:
[HttpPost]
public ActionResult CreateStamp(Stamping stampingmodel)
{
var validateMsg = "";
stampingmodel.Timestamp = DateTime.Now;
stampingmodel.StampingType = "in";
if (stampingmodel.User == null || ModelState.IsValid)
{
var idValidated = db.Users.Find(model.UserId);
if (idValidated != null)
{
var stamp =
db.Stampings.Where(s => s.UserId == stampingmodel.UserId)
.OrderByDescending(s => s.Timestamp)
.FirstOrDefault();
if (stamp.StampingType == stampingmodel.StampingType)
{
if (stampingmodel.StampingType == "in")
{
validateMsg = "Stamped Twice In A Row!";
}
}
else
{
if (stampingmodel.StampingType == "in")
{
validateMsg = "Stamped In, Welcome.";
}
}
}
db.Stampings.Add(stampingmodel);
db.SaveChanges();
}
return Json(new {Message = validateMsg });
JavaScript:
$(document).ready(function () {
$("#stampInBtn").click(function () {
var userId = $("#userId").val();
$.ajax({
url: "ComeAndGo/CreateStamp",
type: "POST",
dataType: "json",
data: {
userId: userId,
}
});
});
View:
<input type="text" id="idUser" class="form-control" />
<br />
<input type="submit" value="IN" id="stampInBtn" />
I have more code inside the View of course; divs, head, body, title and scripts. But it's perhaps a little irrelevant.
What should I do to successfully show those messages?
Regards.
Add a success function to the ajax call
$.ajax({
url: "ComeAndGo/CreateStamp",
type: "POST",
dataType: "json",
data: { userId: userId },
success: function(data) {
// data contains the value returned by the server
console.log(data);
}
});
So if the controller returns
return Json("This is a message");
the value of data will be "This is a message". Note the return value can be a complex type or a partial view
You are getting the value of $("#userId"), but your input has an id of idUser.
Try making your input:
<input type="text" id="userId" class="form-control" />
Also it would be a good idea to provide your Stamping model structure as it seems that you only pass the user id in your post and nothing else.
Change your javascript code as following:
$(document).ready(function () {
$("#stampInBtn").click(function () {
var userId = $("#userId").val();
$.ajax({
url: "ComeAndGo/CreateStamp",
type: "POST",
dataType: "json",
data: {
userId: userId,
},
success: function(data) {
var objData= jQuery.parseJSON(data);
alert(objData.Message );
},
error: function (request, status, error) {
alert(request.responseText);
}
});
});
});
I have a MVC4 single page website with a form. The loading of the contents is achieve with ajax. I do not know how to get the data out from JSON in C#? Here is my code:
JavaScript:
$("#subnt").click(function (event) {
event.preventDefault();
var url = "/Home/Submit";
$.post(url, $('form[name="cnt_us-frm"]').serialize(), function (data) {
if (data.Success === true) {
$("#min-content").hide().load("/Home/PartialSubmit").fadeIn('normal'); // loads the page into 'min-content' section
}
else {
// display error message
}
})
});
});
C#:
[HttpPost]
public JsonResult Submit()
{
return Json(new { Success = true, SomeOtherData = "testing" });
}
Please check below working code -
I have used exactly your working code -
[HttpPost]
public JsonResult Submit()
{
return Json(new { Success = true, SomeOtherData = "testing" });
}
Then I used following JQuery to hit the above action -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click').click(function (e) {
$.ajax({
url: "#Url.Action("Submit")",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (response) {
alert(response);
},
success: function (data) {
if (data.Success == true)
alert(data.SomeOtherData);
}
});
});
});
</script>
<input type="submit" value="click" id="click" />
And as the output I was able to get an alert as shown below -
Easiest thing to do is use the superior json.net
[HttpPost]
public string Submit()
{
var result = new { success = true, someOtherDate = "testing"};
var json = JsonConvert.SerializeObject(result);
return json;
}
Your code is ok bu you can add debugger.and open developer tools check your data .
$.post(url, $('form[name="cnt_us-frm"]').serialize(), function (data) {
debugger;
if (data.Success === true) {
$("#min-content").hide().load("/Home/PartialSubmit").fadeIn('normal'); // loads the page into 'min-content' section
}
else {
// display error message
}
No, the other way around. How to retrieve the data from the form (json).
I haven't worked on Json before,its my first time and as expected I stucked at a point where I want to fill the DropDown with the JsonData.
Here What I am doing is I have an Xml which I am converting in Json like:
string xml = "<Root><Name>A</Name><Name>B</Name><Name>C</Name></Root>";
Then doing this to convert it into JsonString:
XmlDocument doc = new XmlDocument();
doc.LoadXml(Xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
Currently my View is like:
<div>
<input type="button" value="work" name="work" id="idwork" />
</div>
#Html.DropDownListFor(x => x.Name, new SelectList(Enumerable.Empty<SelectListItem>()), new {id="ddl_items" })
Script:
var ddl = $('#ddl_items');
$('#idwork').on('click', function () {
$.ajax({
url: url,
data: {},
type: 'post',
contentType: 'application/json; charset=utf-8',
success: function (myJSONdata) {
$(myJSONdata.Name).each(function () {
ddl.append(
$('<option/>', {
value: this.ReworkTunnelName
}).html(this.Nome)
..
..
});
Now what I want to do is Fill the Dropdown with Names with the help of this JsonData.
please help
$.each(myJSONdata, function ()
{
ddl.append($("<option></option>").attr("value", this.ReworkTunnelName).text(this.Nome));
});
Edit
$.each(myJSONdata, function ()
{
ddl.append($("<option></option>").attr("value", this.ReworkTunnelName).attr("text",this.Nome));
});
$.each(myJSONdata.Root, function ()
{
ddl.append($("<option></option>").attr("text", this.ReworkTunnelName));
});
You can create a new javascript function and pass the dropdown id and json data as parameters in it.
Then you can parse json data as per your data structure. Further run a loop and add items in the select element.
you can use getJSON method in jQuery :
$.getJSON("ActionMethodName", "", function (data) {
$(data).each(function () {
$("<option>").val(this.ReworkTunnelName)
.text(this.Nome)
.appendTo("#ddl_items");
});
});
HTML :
<select id="ddl_items">
<option></option>
</select>
I end up doing this and this is working Fine..
$('#idRework').on('click', function () {
$.ajax({
url: url,
data: {},
type: 'post',
contentType: 'application/json; charset=utf-8',
success: function (myJSONdata) {
var obj = jQuery.parseJSON(myJSONdata);
$.each(obj.Root.ReworkTunnelName, function (index, itemData) {
ddl.append($('<option></option>').val(itemData).html(itemData));
});
}
});
});
Try this
$.each(myJSONdata, function (index, item) {
$('#ddl_items').get(0).options[$('#ddl_items').get(0).options.length] = new Option(item.Text, item.Value);
});
I am pulling my hair. For the love of my life I cannot make this work. I have a form in my view:
<div id="cancel" class="cancel">
<form method="post" class="cancelForm">
<input type="hidden" class="cancelId" name="cancelId" value="#appliedLvl.LeavesId" />
<input id="cancelMe" class="cancelMe" type="submit" value="Cancel"/>
</form>
</div>
The javascript
$(document).ready(function () {
$(".cancelForm").submit(function () {
var MYcancelId = $('.cancelId').val();
$.ajax({
type: "POST",
url: "/Home/Cancel",
success: function (result) {
alert("ok");
},
error: function (request, status, error) {
debugger;
confirm(request);
}
});
})
});
And the Controller
[HttpPost]
public ActionResult Cancel(Guid cancelId )
{
//do stuff here
return PartialView();
}
I always get into the error function of the ajax. No matter what I have tried. This same javascript code works perfectly on my php projects. Don't know what is wrong here. Thanks in advace for any help.
Edit
The error here was the fact that I was expecting in the Action a Guid not a string!
You aren't passing in a cancelId parameter, so it isn't seeing your controller method.
$(document).ready(function () {
$(".cancelForm").submit(function () {
var MYcancelId = $('.cancelId').val();
$.ajax({
type: "POST",
url: "/Home/Cancel",
data: { cancelId = MYcancelId },
success: function (result) {
alert("ok");
},
error: function (request, status, error) {
debugger;
confirm(request);
}
});
})
});