I have this code:
Default.aspx(javascript:)
<script type="text/javascript">
function ShowChartSpider(group_id) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/MethodToCreateChart",
dataType: "json",
data: "{'parameter1':" + JSON.stringify(group_id) + "}",
success: function (data) {
alert("all correct");
console.log(data);
},
error: function (data) {
alert(data);
console.log(data);
}
}
);
}
</script>
Default.aspx.vb
<WebMethod()>
Public Shared Function MethodToCreateChart(parameter1 As String)
WebChartControl1.Series("sectorbuys").Points.Add(New SeriesPoint("value1", "156"))
WebChartControl1.DataBind()
End If
Return ""
End Function
The code in view aspx from the chart is:
<dxchartsui:WebChartControl ID="WebChartControl1" runat="server">
// some code
</dxchartsui:WebChartControl>
So in MethodToCreateChart I can't call my WebChartControl1, but if remove shared I can call the WebChartControl1 control, but the ajax method stops working, so how can I call a control in my aspx keeping my
Public Shared Function MethodToCreateChart?
PageMethod/WebMethod can access the session state but can't access the controls on the page, we can transfer the related property of control as a parameter that you want to get on WebMethod when you call WebMethod on the client.
My page name
public partial class AtamaGorevDegistir : System.Web.UI.Page
{}
My webmethod ajax side
var path = getLocation(location.href);
$.ajax({
type: "POST",
url: path.pathname + "/KisiBilgiDoldur",
// data: "{" + str + "}",
contentType: "application/json; charset=utf-8",
// dataType: "json",
success: function (data) {
var dd = data.d;
$('.modal-dialog').css({ width: '85%' });
$('#AtamaModal').modal({ show: true });
}
});
My webmethod
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string KisiBilgiDoldur(string KayitID, string TeklifID)
{
AtamaGorevDegistir atama = new AtamaGorevDegistir();
atama.AtananSuren.Value = "123";
return null;
}
But my problem my Control is null . But i can access this method but didnt set value and give error message. Why this happened?
WebMethod and ScriptMethod can't access the controls collection of the calling page. Think of it as outside the normal Web Forms lifecycle. When you use AJAX, you need to pass all data to the server side method it needs, and your server side should return all data that the client side needs. Then the client side should take that returned data and manipulate the DOM as necessary to display the result.
In your WebMethod, return the data instead of trying to assign it to a control, remove the return null;.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string KisiBilgiDoldur(string KayitID, string TeklifID)
{
return "123";
}
In your client side success handler, get the returned data and set the value of the control using JavaScript.
var path = getLocation(location.href);
$.ajax({
type: "POST",
url: path.pathname + "/KisiBilgiDoldur",
// data: "{" + str + "}",
contentType: "application/json; charset=utf-8",
// dataType: "json",
success: function (data) {
var dd = data.d;
$('.modal-dialog').css({ width: '85%' });
$('#AtamaModal').modal({ show: true });
//set control value to data.d here
}
});
You don't set the control value with a webmethod. Your return a value and from the api and do something with it, in the browser. Working with webmethods are not like webforms. The value you return in your webmethod is null... you're setting that null value into 'dd' in js, but you don't do anything with it. When you get your value back from the webmethod you need to do something with it. try 'alert(data.d)' in your success callback to see what i mean. Then $('#elm').text(data.d) if you want it on the page.
You should add parameters to data.
$.ajax({
type: "POST",
url: path.pathname + "/KisiBilgiDoldur",
data:JSON.stringify({ KayitID: '1', TeklifID:'2' }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var dd = data.d;
$('.modal-dialog').css({ width: '85%' });
$('#AtamaModal').modal({ show: true });
}
});
I am making an Ajax request with data to a Page Method in my code behind in my ASP.NET Web Forms application. I have a Panel control in my aspx page but I cannot get the control from that Page Method with its ID. I can get it from the Page_Load event though. What can I do to get the Panel control from the page method or is it not possible or maybe an alternative?
<asp:Panel ID="pnlImages" runat="server"></asp:Panel>
<script type="text/javascript">
function GetProductId() {
$.ajax({
type: "POST",
url: "Default.aspx/GenerateQrCode",
data: "{'Products':" + JSON.stringify(data) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(xhr.responseText);
alert(thrownError);
},
success: function (msg) {
alert('Success');
}
});
}
</script>
[WebMethod]
public static void GenerateQrCode(List<Product> Products)
{
foreach(var product in Products)
{
string qrCodeLocation = products.Where(pid=>pid.ProductId == product.ProductId).Select(s=>s.QrCode).FirstOrDefault().ToString();
Image image = new Image();
image.ID = product.ProductId.ToString();
image.ImageUrl = qrCodeLocation;
//Cannot get 'pnlImages' here
}
}
You won't be able to do that, WebMethod doesn't follow the same flow as normal page methods. It's not even a instance method but static.
You'll have to return the information on client and create the image there using javascript.
I am having trouble with the AntiForgeryToken with ajax. I'm using ASP.NET MVC 3. I tried the solution in jQuery Ajax calls and the Html.AntiForgeryToken(). Using that solution, the token is now being passed:
var data = { ... } // with token, key is '__RequestVerificationToken'
$.ajax({
type: "POST",
data: data,
datatype: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
url: myURL,
success: function (response) {
...
},
error: function (response) {
...
}
});
When I remove the [ValidateAntiForgeryToken] attribute just to see if the data (with the token) is being passed as parameters to the controller, I can see that they are being passed. But for some reason, the A required anti-forgery token was not supplied or was invalid. message still pops up when I put the attribute back.
Any ideas?
EDIT
The antiforgerytoken is being generated inside a form, but I'm not using a submit action to submit it. Instead, I'm just getting the token's value using jquery and then trying to ajax post that.
Here is the form that contains the token, and is located at the top master page:
<form id="__AjaxAntiForgeryForm" action="#" method="post">
#Html.AntiForgeryToken()
</form>
You have incorrectly specified the contentType to application/json.
Here's an example of how this might work.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string someValue)
{
return Json(new { someValue = someValue });
}
}
View:
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
#Html.AntiForgeryToken()
}
<div id="myDiv" data-url="#Url.Action("Index", "Home")">
Click me to send an AJAX request to a controller action
decorated with the [ValidateAntiForgeryToken] attribute
</div>
<script type="text/javascript">
$('#myDiv').submit(function () {
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
url: $(this).data('url'),
type: 'POST',
data: {
__RequestVerificationToken: token,
someValue: 'some value'
},
success: function (result) {
alert(result.someValue);
}
});
return false;
});
</script>
Another (less javascriptish) approach, that I did, goes something like this:
First, an Html helper
public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper)
{
var antiForgeryInputTag = helper.AntiForgeryToken().ToString();
// Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="PnQE7R0MIBBAzC7SqtVvwrJpGbRvPgzWHo5dSyoSaZoabRjf9pCyzjujYBU_qKDJmwIOiPRDwBV1TNVdXFVgzAvN9_l2yt9-nf4Owif0qIDz7WRAmydVPIm6_pmJAI--wvvFQO7g0VvoFArFtAR2v6Ch1wmXCZ89v0-lNOGZLZc1" />
var removedStart = antiForgeryInputTag.Replace(#"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", "");
var tokenValue = removedStart.Replace(#""" />", "");
if (antiForgeryInputTag == removedStart || removedStart == tokenValue)
throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect.");
return new MvcHtmlString(string.Format(#"{0}:""{1}""", "__RequestVerificationToken", tokenValue));
}
that will return a string
__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
so we can use it like this
$(function () {
$("#submit-list").click(function () {
$.ajax({
url: '#Url.Action("SortDataSourceLibraries")',
data: { items: $(".sortable").sortable('toArray'), #Html.AntiForgeryTokenForAjaxPost() },
type: 'post',
traditional: true
});
});
});
And it seems to work!
it is so simple! when you use #Html.AntiForgeryToken() in your html code it means that server has signed this page and each request that is sent to server from this particular page has a sign that is prevented to send a fake request by hackers. so for this page to be authenticated by the server you should go through two steps:
1.send a parameter named __RequestVerificationToken and to gets its value use codes below:
<script type="text/javascript">
function gettoken() {
var token = '#Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
</script>
for example take an ajax call
$.ajax({
type: "POST",
url: "/Account/Login",
data: {
__RequestVerificationToken: gettoken(),
uname: uname,
pass: pass
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
success: successFu,
});
and step 2 just decorate your action method by [ValidateAntiForgeryToken]
In Asp.Net Core you can request the token directly, as documented:
#inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
#functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
And use it in javascript:
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": '#GetAntiXsrfRequestToken()' });
}
You can add the recommended global filter, as documented:
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
Update
The above solution works in scripts that are part of the .cshtml. If this is not the case then you can't use this directly. My solution was to use a hidden field to store the value first.
My workaround, still using GetAntiXsrfRequestToken:
When there is no form:
<input type="hidden" id="RequestVerificationToken" value="#GetAntiXsrfRequestToken()">
The name attribute can be omitted since I use the id attribute.
Each form includes this token. So instead of adding yet another copy of the same token in a hidden field, you can also search for an existing field by name. Please note: there can be multiple forms inside a document, so name is in that case not unique. Unlike an id attribute that should be unique.
In the script, find by id:
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": $('#RequestVerificationToken').val() });
}
An alternative, without having to reference the token, is to submit the form with script.
Sample form:
<form id="my_form" action="/something/todo/create" method="post">
</form>
The token is automatically added to the form as a hidden field:
<form id="my_form" action="/something/todo/create" method="post">
<input name="__RequestVerificationToken" type="hidden" value="Cf..." /></form>
And submit in the script:
function DoSomething() {
$('#my_form').submit();
}
Or using a post method:
function DoSomething() {
var form = $('#my_form');
$.post("/something/todo/create", form.serialize());
}
In Asp.Net MVC when you use #Html.AntiForgeryToken() Razor creates a hidden input field with name __RequestVerificationToken to store tokens. If you want to write an AJAX implementation you have to fetch this token yourself and pass it as a parameter to the server so it can be validated.
Step 1: Get the token
var token = $('input[name="`__RequestVerificationToken`"]').val();
Step 2: Pass the token in the AJAX call
function registerStudent() {
var student = {
"FirstName": $('#fName').val(),
"LastName": $('#lName').val(),
"Email": $('#email').val(),
"Phone": $('#phone').val(),
};
$.ajax({
url: '/Student/RegisterStudent',
type: 'POST',
data: {
__RequestVerificationToken:token,
student: student,
},
dataType: 'JSON',
contentType:'application/x-www-form-urlencoded; charset=utf-8',
success: function (response) {
if (response.result == "Success") {
alert('Student Registered Succesfully!')
}
},
error: function (x,h,r) {
alert('Something went wrong')
}
})
};
Note: The content type should be 'application/x-www-form-urlencoded; charset=utf-8'
I have uploaded the project on Github; you can download and try it.
https://github.com/lambda2016/AjaxValidateAntiForgeryToken
function DeletePersonel(id) {
var data = new FormData();
data.append("__RequestVerificationToken", "#HtmlHelper.GetAntiForgeryToken()");
$.ajax({
type: 'POST',
url: '/Personel/Delete/' + id,
data: data,
cache: false,
processData: false,
contentType: false,
success: function (result) {
}
});
}
public static class HtmlHelper
{
public static string GetAntiForgeryToken()
{
System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), "(?:value=\")(.*)(?:\")");
if (value.Success)
{
return value.Groups[1].Value;
}
return "";
}
}
In Account controller:
// POST: /Account/SendVerificationCodeSMS
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public JsonResult SendVerificationCodeSMS(string PhoneNumber)
{
return Json(PhoneNumber);
}
In View:
$.ajax(
{
url: "/Account/SendVerificationCodeSMS",
method: "POST",
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
dataType: "json",
data: {
PhoneNumber: $('[name="PhoneNumber"]').val(),
__RequestVerificationToken: $('[name="__RequestVerificationToken"]').val()
},
success: function (data, textStatus, jqXHR) {
if (textStatus == "success") {
alert(data);
// Do something on page
}
else {
// Do something on page
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus);
console.log(jqXHR.status);
console.log(jqXHR.statusText);
console.log(jqXHR.responseText);
}
});
It is important to set contentType to 'application/x-www-form-urlencoded; charset=utf-8' or just omit contentTypefrom the object ...
I know this is an old question. But I will add my answer anyway, might help someone like me.
If you dont want to process the result from the controller's post action, like calling the LoggOff method of Accounts controller, you could do as the following version of #DarinDimitrov 's answer:
#using (Html.BeginForm("LoggOff", "Accounts", FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
#Html.AntiForgeryToken()
}
<!-- this could be a button -->
Submit
<script type="text/javascript">
$('#ajaxSubmit').click(function () {
$('#__AjaxAntiForgeryForm').submit();
return false;
});
</script>
For me the solution was to send the token as a header instead of as a data in the ajax call:
$.ajax({
type: "POST",
url: destinationUrl,
data: someData,
headers:{
"RequestVerificationToken": token
},
dataType: "json",
success: function (response) {
successCallback(response);
},
error: function (xhr, status, error) {
// handle failure
}
});
The token won't work if it was supplied by a different controller. E.g. it won't work if the view was returned by the Accounts controller, but you POST to the Clients controller.
I tried a lot of workarrounds and non of them worked for me. The exception was "The required anti-forgery form field "__RequestVerificationToken" .
What helped me out was to switch form .ajax to .post:
$.post(
url,
$(formId).serialize(),
function (data) {
$(formId).html(data);
});
Feel free to use the function below:
function AjaxPostWithAntiForgeryToken(destinationUrl, successCallback) {
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
type: "POST",
url: destinationUrl,
data: { __RequestVerificationToken: token }, // Your other data will go here
dataType: "json",
success: function (response) {
successCallback(response);
},
error: function (xhr, status, error) {
// handle failure
}
});
}
Create a method that will responsible to add token
var addAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $("[name='__RequestVerificationToken']").val();
return data;
};
Now use this method while passing data/parameters to Action like below
var Query = $("#Query").val();
$.ajax({
url: '#Url.Action("GetData", "DataCheck")',
type: "POST",
data: addAntiForgeryToken({ Query: Query }),
dataType: 'JSON',
success: function (data) {
if (data.message == "Success") {
$('#itemtable').html(data.List);
return false;
}
},
error: function (xhr) {
$.notify({
message: 'Error',
status: 'danger',
pos: 'bottom-right'
});
}
});
Here my Action have a single parameter of string type
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult GetData( string Query)
{
#using (Ajax.BeginForm("SendInvitation", "Profile",
new AjaxOptions { HttpMethod = "POST", OnSuccess = "SendInvitationFn" },
new { #class = "form-horizontal", id = "invitation-form" }))
{
#Html.AntiForgeryToken()
<span class="red" id="invitation-result">#Html.ValidationSummary()</span>
<div class="modal-body">
<div class="row-fluid marg-b-15">
<label class="block">
</label>
<input type="text" id="EmailTo" name="EmailTo" placeholder="forExample#gmail.com" value="" />
</div>
</div>
<div class="modal-footer right">
<div class="row-fluid">
<button type="submit" class="btn btn-changepass-new">send</button>
</div>
</div>
}
I've been working on this for 3 hours and have given up.
I am simply trying to send data to an ASP.NET WebMethod, using jQuery.
The data is basically a bunch of key/value pairs. So I've tried to create an array and adding the pairs to that array.
My WebMethod (aspx.cs) looks like this (this may be wrong for what I'm building in JavaScript, I just don't know):
[WebMethod]
public static string SaveRecord(List<object> items)
{
...
}
Here is my sample JavaScript:
var items = new Array;
var data1 = { compId: "1", formId: "531" };
var data2 = { compId: "2", formId: "77" };
var data3 = { compId: "3", formId: "99" };
var data4 = { status: "2", statusId: "8" };
var data5 = { name: "Value", value: "myValue" };
items[0] = data1;
items[1] = data2;
items[2] = data3;
items[3] = data4;
items[4] = data5;
Here is my jQuery AJAX call:
var options = {
error: function(msg) {
alert(msg.d);
},
type: "POST",
url: "PackageList.aspx/SaveRecord",
data: { 'items': items },
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function(response) {
var results = response.d;
}
};
jQuery.ajax(options);
I get the error:
Invalid JSON primitive: items.
So, if I do this:
var DTO = { 'items': items };
and set the data parameter like this:
data: JSON.stringify(DTO)
Then I get this error:
Cannot convert object of type \u0027System.String\u0027 to type \u0027System.Collections.Generic.List`1[System.Object]\u0027
In your example, it should work if your data parameter is:
data: "{'items':" + JSON.stringify(items) + "}"
Keep in mind that you need to send a JSON string to ASP.NET AJAX. If you specify an actual JSON object as jQuery's data parameter, it will serialize it as &k=v?k=v pairs instead.
It looks like you've read it already, but take another look at my example of using a JavaScript DTO with jQuery, JSON.stringify, and ASP.NET AJAX. It covers everything you need to make this work.
Note: You should never use JavaScriptSerializer to manually deserialize JSON in a "ScriptService" (as suggested by someone else). It automatically does this for you, based on the specified types of the parameters to your method. If you find yourself doing that, you are doing it wrong.
When using AJAX.NET I always make the input parameter just a plain old object and then use the javascript deserializer to covert it to whatever type I want. At least that way you can debug and see what type of object the web method in is recieving.
You need to convert your object to a string when using jQuery
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true">
<Scripts>
<asp:ScriptReference Path="~/js/jquery.js" />
</Scripts>
</asp:ScriptManager>
<div></div>
</form>
</body>
</html>
<script type="text/javascript" language="javascript">
var items = [{ compId: "1", formId: "531" },
{ compId: "2", formId: "77" },
{ compId: "3", formId: "99" },
{ status: "2", statusId: "8" },
{ name: "Value", value: "myValue"}];
//Using Ajax.Net Method
PageMethods.SubmitItems(items,
function(response) { var results = response.d; },
function(msg) { alert(msg.d) },
null);
//using jQuery ajax Method
var options = { error: function(msg) { alert(msg.d); },
type: "POST", url: "WebForm1.aspx/SubmitItems",
data: {"items":items.toString()}, // array to string fixes it *
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function(response) { var results = response.d; } };
jQuery.ajax(options);
</script>
And the Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CustomEquip
{
[ScriptService]
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static void SubmitItems(object items)
{
//break point here
List<object> lstItems = new JavaScriptSerializer().ConvertToType<List<object>>(items);
}
}
}
The following is a code snippet from our project - I had trouble with not wrapping the object as a string and also with Date values - hopefully this helps someone:
// our JSON data has to be a STRING - need to send a JSON string to ASP.NET AJAX.
// if we specify an actual JSON object as jQuery's data parameter, it will serialize it as ?k=v&k=v pairs instead
// we must also wrap the object we are sending with the name of the parameter on the server side – in this case, "invoiceLine"
var jsonString = "{\"invoiceLine\":" + JSON.stringify(selectedInvoiceLine) + "}";
// reformat the Date values so they are deserialized properly by ASP.NET JSON Deserializer
jsonString = jsonString.replace(/\/Date\((-?[0-9]+)\)\//g, "\\/Date($1)\\/");
$.ajax({
type: "POST",
url: "InvoiceDetails.aspx/SaveInvoiceLineItem",
data: jsonString,
contentType: "application/json; charset=utf-8",
dataType: "json"
});
The server method signature looks like this:
[WebMethod]
public static void SaveInvoiceLineItem(InvoiceLineBO invoiceLine)
{
Decorate your [WebMethod] with another attribute:
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
I believe this is in System.Web.Services.Scripting...
see link http://www.andrewrowland.com/article/display/consume-dot-net-web-service-with-jquery
This is the way you define your data (JSON)
data: { 'items': items },
and the this the way it should be
data: '{ items: " '+items +' "}',
basically you are serializing the parameter.