Passing AntiForgeryToken using AJAX - javascript

I make my EDIT view a dialog box and i need to pass AntiForgeryToken with it. But I've tried several times and still I can't pass it.
$("#EditSave").click(function(e) {
e.preventDefault();
$.ajax({
url: 'PIS/Edit',
type: "POST",
dataType: 'json',
data: $('form').serialize(),
success: function (data) {
if (data.Save) {
dialog.dialog('close');
var notification = {
type: "success",
title: "Successfully",
message: "save ",
icon: 'glyphicon glyphicon-ok-sign'
};
showNotification(notification);
updatePartial();
}
if (data.AlreadyExist) {
var notification = {
type: "danger",
title: "Warning!",
message: "Already Exist",
icon: 'glyphicon glyphicon-exclamation-sign'
};
showNotification(notification);
}
if (data.Back) {
var notification = {
type: "danger",
title: "Warning!",
message: "Information was not successfully saved. Please check required fields.",
icon: 'glyphicon glyphicon-exclamation-sign'
};
showNotification(notification);
}
else {
debugger
dialog.dialog('close');
}
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
})
return false;
})
This is my controller action and I need to pass the token on my view so that cross-side scripting can be prevented because this is an Edit view in a form of a dialog box.
public async Task<PartialViewResult> Edit(string id)
{
return PartialView();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<JsonResult>Edit(PISEditViewModel viewModel)
{
return Json(new {Back = true });
}
This is the error message i got when passing $('form').serialize()
The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the <machineKey> configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster.

Related

AJAX Post call no data

Hello wenn i want to send a post request to my Controller there is no data.
I tried to log my Json file and there is something. But when I send the post request my controller shows it is empty.
Here is my call:
var item = {};
var jsonObj = [];
item["ProductCategoryId"] = i;
item["Name"] = txtName;
item["Description"] = txtDescription;
item["Price"] = txtPrice;
item["Stock"] = txtStock;
item["ProductCategory"] = txtProductCategory;
item["Image"] = await getAsByteArray(txtImage);
jsonObj.push(item);
var jsonString = JSON.stringify(jsonObj);
console.log("jsonString : " + jsonString);
$.ajax({
url: "/Admin/SaveProductToDB",
type: "POST",
data: { dataToSend: jsonString},
success: function (data) {
if (data.status == "Success") {
BootstrapDialog.show({
title: 'Success!',
message: "Data Updated Successfully!",
buttons: [{
label: 'OK',
action: function (dialog) {
window.location.href = "/Admin/Product";
removeProdData(i);
$("#btnAddProd").attr("disabled",false);
dialog.close();
}
}]
});
}
}
});
//Here I make a breakpoint but my string is empty
public JsonResult SaveProductToDB(string dataToSend)
{
List<Product> _List = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Product>>(dataToSend);
}
the getAsByteArray
async function getAsByteArray(file) {
return new Uint8Array(await readFile(file))
}
function readFile(file) {
return new Promise((resolve, reject) => {
// Create file reader
let reader = new FileReader()
// Register event listeners
reader.addEventListener("loadend", e => resolve(e.target.result))
reader.addEventListener("error", reject)
// Read file
reader.readAsArrayBuffer(file)
})
}
I found out if I remove the Image. that the controller is then able to resize it. Thanks for the help so far. So I need to look at this place where the problem is.
You are checking against data.status as if it's a given that it exists. Just console.log(data) instead and you will see whether or not status is being returned.
Also, if you open the Network tab in Chrome you can click on the post request & see if your headers are going through accurately and also click on 'Preview' to see an unfiltered result from the controller.
You might want to modify your code to catch errors for debugging, ie:
$.ajax({
url: "/Admin/SaveProductToDB",
type: "POST",
data: { dataToSend: jsonString},
success: function (data) {
if (data.status == "Success") {
BootstrapDialog.show({
title: 'Success!',
message: "Data Updated Successfully!",
buttons: [{
label: 'OK',
action: function (dialog) {
window.location.href = "/Admin/Product";
removeProdData(i);
$("#btnAddProd").attr("disabled",false);
dialog.close();
}
}]
});
}
},
error:function (xhr, ajaxOptions, thrownError) {
// Set up whatever error reaction you want, here. ie:
console.log('An error was encountered.');
alert(xhr.status);
alert(thrownError);
}
});
Another tip is to validate empty data being submitted prior to the Ajax call, so you only touch the backend server when your data is valid - to avoid an error.

Why am I getting json response page after ajax post call?

I have an aps.net MVC5 web app, I have a controller action post method that looks like this,
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Set(int id)
{
DbHelper dbHelper = new DbHelper();
dbHelper.Update<News>("update news set ispublished = 1, publishdate = #PublishDate where newsid = #NewsId", new { NewsId = id, PublishDate = DateTime.Now });
return Json(new { success = true, message = "added successfully!", redirectToUrl = Url.Action("NewsList", "Home") }, JsonRequestBehavior.AllowGet);
}
Now, when I call this method from my View ,
$(document).on("click", ".set", function () {
var mId = $(this).attr("data-model-id");
$.ajax({
url: "#Url.Action("Set","Home")",
data: { "id": mId },
contentType: 'application/json',
type: 'POST',
dataType:'json',
success: function (response) {
if (response.success) {
window.location.href = response.redirectToUrl;
dt.ajax.reload();
$.notify(data.message, {
globalPosition: "top center",
className: "success"
});
}
},
error: function (response) {
$.notify(response.message, {
globalPosition: "top center",
className: "success"
});
}
});
});
I am always getting this enter image description here
I expect to be redirected to home/newslist url. I tried changing all the parameters of ajax call , adding and removing them, still no matter what I do, I always land at this page.
Try to check after remove the "error" function from your ajax. Also you can try this:
$(document).on("click", ".set", function () {
var mId = $(this).attr("data-model-id");
$.ajax({
url: "#Url.Action("Set","Home")",
data: { "id": mId },
contentType: 'application/json',
type: 'POST',
dataType:'json',
success: function (response) {
if (response.success) {
window.location.href = response.redirectToUrl;
dt.ajax.reload();
$.notify(data.message, {
globalPosition: "top center",
className: "success"
});
}
},
error: function (jqXHR, textStatus, errorThrown) {
$.notify(errorThrown, {
globalPosition: "top center",
className: "success"
});
}
});
});
Check if success function is calling or not.
If you need return the full HTML page in ajax response then you need to change Controller method with some changes.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Set(int id)
{
DbHelper dbHelper = new DbHelper();
dbHelper.Update<News>("update news set ispublished = 1, publishdate = #PublishDate where newsid = #NewsId", new { NewsId = id, PublishDate = DateTime.Now });
//return Json(new { success = true, message = "added successfully!", redirectToUrl = Url.Action("NewsList", "Home") }, JsonRequestBehavior.AllowGet);
return view("ViewName");
}

ASP.NET MVC POST Route does not point to the correct Method

I´ve got a problem with my current mvc project.
I´m using an ajax call to send new comments to the server but the method does not even get called.
My js code:
$("#answer_button").click(function () {
showLoadingTab();
var actionUrl = '#Url.Action("AnswerThread", "Threads")';
var threadId = $("#threadId").val();
var msg = $("#answer_msg").val();
alert(actionUrl);
alert(msg);
alert(threadId);
$.ajax({
url: actionUrl,
type: "POST",
data: "Message=" + msg + "&threadId=" + threadId,
success: function (msg) {
hideLoadingTab();
location.reload();
},
error: function () {
alert("Ein Fehler ist aufgetreten.");
hideLoadingTab();
}
});
});
as you see I´ve alerted the url, msg and threadId and they are all correct. url: "/Threads/AnswerThread", msg: "test", threadId: 1.
I´ve already tried to put a breakpoint inside the AnswerThread method but it does not get called. The "AnswerThread" method is inside the "ThreadsController" and looks like this:
[HttpPost]
public ActionResult AnswerThread(string Message, int threadId)
{
var userId = User.Identity.GetUserId();
using (var db = new UnitOfWork(new BlogContext()))
{
db.Posts.Add(new Post()
{
Message = Message,
PublishTime = DateTime.Now,
ThreadId = threadId,
UserId = userId
});
db.Complete();
}
return PartialView("/Views/Partial/Clear.cshtml");
}
That´s exactly the same way I did it in the backend controllers but there it just works fine.
I hope somebody can help me..
UPDATE:
Made some changes just to try if any other way works.
Change1 js:
var data = {
threadId: threadId,
Message: msg
};
$.ajax({
url: actionUrl,
type: "POST",
content: "application/json; charset=utf-8",
dataType: "json",
data: data,
success: function (msg) {
if (msg.success == true) {
hideLoadingTab();
location.reload();
}
else
{
alert("Ein Fehler ist aufgetreten: " + msg.error);
}
},
error: function () {
alert("Ein Fehler ist aufgetreten.");
hideLoadingTab();
}
});
Change 2 c#:
[HttpPost]
public JsonResult AnswerThread([System.Web.Http.FromBody]PostDataModel data)
{
var userId = User.Identity.GetUserId();
string error = "";
bool success = false;
try
{
using (var db = new UnitOfWork(new BlogContext()))
{
db.Posts.Add(new Post()
{
Message = data.Message,
PublishTime = DateTime.Now,
ThreadId = data.threadId,
UserId = userId
});
success = true;
db.Complete();
}
}
catch(Exception ex)
{
error = ex.Message;
}
return Json(String.Format("'Success':'{0}', 'Error':'{1}'", success, error));
I tried this now with and without the "[FromBody]" statement.
Oh yes and I´ve added the DataModel like this:
public class PostDataModel
{
public int threadId { get; set; }
public string Message { get; set; }
}
and I also tried to manually configure the pointed route.
routes.MapRoute(
name: "AnswerThread",
url: "threads/answer",
defaults: new { controller = "Threads", action = "AnswerThread" }
);
The "actionUrl" variable in js get´s changed to /threads/answer but I´m always getting 500 Internal Server Error. When I put a breakpoint inside the method it does not stop at any point of the ajax call.
In the Chrome Dev Tools at the "Network" tab it says to me that there is a parameter called "id" which is null which causes to this 500 internal server error. I tried to find out more information about this but the error does not tell me where this parameter is located.
I´ve got no parameter called "id" inside this method or the data model so where does this come from?
Solution:
My Routes mapping was bad. I first mapped the route /threads/{id} and THEN did /threads/answer so when the /threads/answer got called it thought "answer" is an id so it tried to enter the "Index" method. So for my particular problem (and maybe for some other guys having the same issue) the solution was just to put the mapping of the /threads/answer route in front of the /threads/{id} route and it worked.
Please check your parameter types, in controller threadId is int type and from ajax call you are passing string type.
In Js
$("#answer_button").click(function () {
showLoadingTab();
var actionUrl = '#Url.Action("AnswerThread", "Home")';
var threadId = parseInt($("#threadId").val());
var msg = "Answer message";
alert(threadId);
$.ajax({
url: actionUrl,
type: "POST",
data: { Message: msg, threadId: threadId },
success: function (msg) {
hideLoadingTab();
location.reload();
},
error: function () {
alert("Ein Fehler ist aufgetreten.");
hideLoadingTab();
}
});
});
In Controller
[HttpPost]
public ActionResult AnswerThread(string Message, int threadId)
{
return Json("Data");
}

How to send JSON to a Web API?

I'm making a website with web API, I tried to send JSON to my controller but this is the error I keep getting.
Multiple actions were found that match the request:
Post on type AuctionWebsiteASP.Controllers.MovesController
readDatabase on type AuctionWebsiteASP.Controllers.MovesController
newItem on type AuctionWebsiteASP.Controllers.MovesController
First I tried searching for a fix but none of the fixes here helped.
My Controller
public class MovesController : ApiController
{
[AcceptVerbs("GET", "POST")]
public HttpResponseMessage Post([FromBody] Product product)
{
products.Add(product);
newItem();
return Request.CreateResponse(HttpStatusCode.OK, product);
}
}
My JS
$.ajax({
type: "POST",
dataType: "json",
url: "/api/moves/",
data: source,
success: function (data) {
$("#nStart").val(null);
$("#nImg").val(null);
$("#nMaker").val(null);
$("#nModel").val(null);
$("#nSerial").val(null);
$("#nCpu").val(null);
$("#nRam").val(null);
$("#nGpu").val(null);
$("#nStorage").val(null);
$("#nBattery").val(null);
$("#nDrivers").val(null);
$("#nAccessories").val(null);
$("#nNotes").val(null);
console.log("Data has been sent!");
},
error: function (error) {
jsonValue = jQuery.parseJSON(error.responseText);
alert("ERROR!");
}
});
Thanks in advance!
Your route is probably like this
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
But in order to have multiple actions with the same http method you need to provide webapi with more information via the route like so:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
Try to use Route attribute to distinguish each action e.g
public class MovesController : ApiController
{
[Route("Product")]
public HttpResponseMessage Post([FromBody] Product product)
{
products.Add(product);
newItem();
return Request.CreateResponse(HttpStatusCode.OK, product);
}
}
$.ajax({
type: "POST",
dataType: "json",
url: "/api/moves/product",
data: source,
success: function (data) {
$("#nStart").val(null);
$("#nImg").val(null);
$("#nMaker").val(null);
$("#nModel").val(null);
$("#nSerial").val(null);
$("#nCpu").val(null);
$("#nRam").val(null);
$("#nGpu").val(null);
$("#nStorage").val(null);
$("#nBattery").val(null);
$("#nDrivers").val(null);
$("#nAccessories").val(null);
$("#nNotes").val(null);
console.log("Data has been sent!");
},
error: function (error) {
jsonValue = jQuery.parseJSON(error.responseText);
alert("ERROR!");
}
});

jquery ajax call not hitting c# webmethod. Hits page load though.

I can't figure out why my Javascript ajax call won't hit my c# method. I build this up in my code behind.
ScriptManager.RegisterStartupScript(this, GetType(), "alertMessage", #"swal.withForm({
title: 'Database Credentials',
formFields: [{
id: 'server',
placeholder: 'Server Name'
}, {
id: 'username',
placeholder: 'User Name'
}, {
id: 'password',
placeholder: 'Password',
type: 'password'
}, {
id: 'databaseName',
placeholder: 'Database Name'
}],
html: true,
confirmButtonText: 'Update'
}, function(isConfirm) {
console.log(JSON.stringify(this.swalForm));
$.ajax({
type: 'GET',
url: 'WebMethods.aspx/CheckCreateDatabase',
contentType: 'application / json; charset = utf - 8',
dataType: 'html',
data: JSON.stringify(this.swalForm),
success: function(data) {
swal('Success ' + data);
},
error: function(data, success, error) {
swal('Error ' + error);
}
});
});", true);
The console outputs this result for the json string, based on my inputs.
{"server":"dfd","username":"df","password":"dfd","databaseName":"dfd"}
My code behind
public partial class WebMethods : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var a = "a";
}
[WebMethod]
public static string CheckCreateDatabase(string server, string username, string password, string databaseName)
{
return "it worked";
}
}
It will hit my break point in the page load event, but it won't hit it in the CheckCreateDatabase block.
I tried a bunch of different posts and still can't get it to hit that method.
Does anyone see anything wrong or anything I can look into. Thanks.
I figured it out. I copied the contenttype from a website and it had spaces in it. That was messing it up.

Categories