I've integrated the Charisma V.2.0.0 bundle in an ASP.Net C# application. All looks good until I write an .ajax call to a web service. Ajax call, a standard format, works in a basic asp.net page, but from the bundle. It seems like something in his 'bower_components'. I removed reference to bower_components/jquery and am including ajax.googleapis.com... 3.3.1.
Does anyone have experience with this problem? and what might be a solution? I like the UI Muhammad designed and would like to keep developing which is platform.
The axax call looks like this:
// Edit Client button
$(document).on("click", "[id*=btnEditClient]", function () {
// Edit selected client/Event Id - get data from Ajax
//alert($(this).val());
var clientId = $(this).val();
var clientInfo = JSON.stringify({ clientId: clientId });
alert(clientInfo);
$.ajax(
{
url: '<%= ResolveUrl("QRWebService.aspx/GetClientListService") %>',
type: "POST",
data: clientInfo,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
// results
alert(result.d);
alert('no error ' + JSON.stringify(result));
$("#myModal").modal()
return true;
},
error: function (jqXHR, textStatus, errorThrown) {
alert('error: ' + textStatus);
}
});
return false;
})
and the result is 'undefined' where the web service never gets called.
The web serivce is:
[WebMethod]
public static DataSet GetClientListService()
{
// returns dataset LIST of Client Id and Name
DataSet ds = new DataSet();
SQLHelper.SqlQuery oQuery = new SQLHelper.SqlQuery();
String strSQL;
try
{
strSQL = "SELECT Clients.ClientId, ClientName FROM Clients ";
strSQL += "WHERE ClientActive=#clientActive";
ds = oQuery.GetDataSet(strSQL);
} catch(Exception ex){
errorMessage = ex.Message;
}
return ds;
} // end GetClientEventList()
Post ASP.NET Calling WebMethod with jQuery AJAX "401 (Unauthorized)". Changing the App_Start from Permanent to:
settings.AutoRedirectMode = RedirectMode.Off;
did the trick. I hope this helps others. Thank you StackOverflow and all those who post solutions to tricky issues.
Hello I have one registration form of users as soon as user register in next browser tab i will get that registered user details without page refresh for this i got code from github project and tested that which is working perfectly and I have loaded jquery,socket.js file in both pages (data post,retrieving page)as they mentioned in that still i am not getting latest registered users without page refresh ,so please tell me where the code need to be correct.below is my code
code to post data(register users)
$("#submit").click(function(event){
event.preventDefault();
var dataString = {
name : $("#name").val(),
email : $("#wickets").val()
};
$.ajax({
url: "<?= base_url('User/register') ?>",
type: "POST",
data: dataString,
dataType: "json",
cache : false,
success: function (data) {
if (data.success == true) {
var socket = io.connect( 'http://'+window.location.hostname +':3000' );
socket.emit('registered_users', {
name: data.name,
email: data.email
});
}
}, error: function (xhr, status, error) {
alert(error);
},
});
});
code to get name and email of user who have just register by socket
html div tags to print user name and email
<div id="user_name"></div>
<div id="user_email"></div>
script for socket
var socket = io.connect( 'http://'+window.location.hostname+':3000' );
socket.on( 'registered_users', function( data ) {
$( "#user_name" ).prepend( data.name );
$( "#user_email" ).prepend( data.email );
});
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>
}
Currently I have a main view called getRolesByYear.cshtml. In this view I have three buttons, each for an year. When I click a button(or on page load) I invoke a method, which takes an int 'year' for a parameter and calls an ajax with the year parameter. This ajax calls an action method (getRolesByYear, the one for the main view). The Action method makes a query to a database, a result of which is a list of ViewModel objects. In the return statement I return a PartialView like this : return PartialView("_yearlyRoles",list);. Sadly, after all this, instead of getting a list of the desired objects in my frontend, all i get is an error from the error part of the ajax call. I am generally a novice and I am very stuck with this.
Here is the main view getRolesByYear.cshtml:
#{
ViewBag.Title = "getRolesByYear";
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
getRolesForYear(parseInt(#DateTime.Now.Year));
$(function () {
$('#years a').click(function () {
var year = $(this).text();
console.log(year);
getRolesForYear(parseInt(year));
});
})
//console.log(year);
function getRolesForYear(year) {
console.log(year);
$.ajax({
type: "POST",
url: '#Url.Action("getRolesByYear", "WorkRoles")',
dataType: "json",
data: {
year: year
},
success: successFunc,
error: errorFunc
});
function successFunc(data, status) {
$("#partial").html(data);
}
function errorFunc() {
alert('error');
}
}
</script>
<div id = "years" class="btn-group btn-group-justified timeline">
#DateTime.Now.Year
#DateTime.Now.AddYears(-1).Year
#DateTime.Now.AddYears(-2).Year
</div>
<div id = "partial"></div>
The partial view :
#model IEnumerable<eksp.Models.RoleViewModel>
#foreach (var item in Model)
{
<div class="jumbotron">
<h2>item.Role.RoleName</h2>
<h1> item.Role.RoleDescription</h1>
<p class="lead">Focus start : item.Role.FocusStart</p>
<p>Focus end : item.Role.FocusStart </p>
</div>
}
The Action Method :
[HttpPost]
public ActionResult getRolesByYear(int year)
{
string currentUserId = User.Identity.GetUserId();
var list = db.WorkRoles.
Join(db.WorkRolesUsersDetails,
o => o.WorkRoleId, od => od.WorkRoleId,
(o, od) => new
{
WorkRoleId = o.WorkRoleId,
RoleName = o.RoleName,
RoleDescription = o.RoleDescription,
CompanyId = o.CompanyId,
WRUDId = od.WRUDId,
UserDetailsId = od.UserDetailsId,
FocusStart = od.FocusStart,
FocusEnd = od.FocusEnd
}).ToList()
.Select(item => new RoleViewModel(
item.WorkRoleId,
item.RoleName,
item.RoleDescription,
item.CompanyId,
item.WRUDId,
item.UserDetailsId,
item.FocusStart,
item.FocusEnd)).ToList();
//RoleViewModel rv = list;
if (Request.IsAjaxRequest())
{
return PartialView("_yearlyRoles", list);
}
else
{
return View(list);
}
}
Given the reported error message, you need to alter your ajax call. By setting "data" parameter to "json" you're telling ajax to expect JSON-formatted data back in the response, but a partial view is HTML, so change your ajax call to reflect this:
$.ajax({
type: "POST",
url: '#Url.Action("getRolesByYear", "WorkRoles")/' + year,
dataType: "html", //set the correct data type for the response
success: successFunc,
error: errorFunc
});
As an aside, you can improve your error handling on the client side quite straightforwardly by changing errorFunc to something like this, using the parameters that are provided to the callback by $.ajax:
function errorFunc(jQXHR, textStatus, errorThrown) {
alert("An error occurred while trying to contact the server: " + jQXHR.status + " " + textStatus + " " + errorThrown);
}
For less instrusive reporting and/or easier debugging, you could change the alert to console.log. To get more detail you could also log the entire jQXHR object:
console.log(JSON.stringify(jQXHR));
So I have a partialview and I have 2 forms inside it as below:
#using (Html.BeginForm("AddAlbum", "Admin", FormMethod.Post, htmlAttributes: new { id = "frmAlbumAdd", novalidate = "novalidate", autocomplete = "off" }))
{
#Html.AntiForgeryToken()
<!--some controls and submit button-->
}
.....
.....
#using (Html.BeginForm("UploadImages", "Admin", FormMethod.Post, htmlAttributes: new { id = "frmUploadImages", novalidate = "novalidate", autocomplete = "off", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<!--some controls and submit button-->
}
and I am doing ajax post to the Admin controller as below:
[HttpPost]
[ValidateAntiForgeryToken]//This works well
public JsonResult AddAlbum(AlbumDataModel model)
{
//perform some task and return result
}
[HttpPost]
[ValidateAntiForgeryToken]//This results in Error
public JsonResult UploadImages([Bind(Prefix = "UIAModel")] UploadImageAlbum model)
{
//perform some task and return result
}
and the error I get on second form submission is "The required anti-forgery form field \"__RequestVerificationToken\" is not present."
According to this post in SO we can have antiforgerytokens for different forms individually. But am not sure why this turns out to be error.
I've also tried adding #Html.AntiForgeryToken() in the Layout where partialviews load and excluded it from forms and had below ajaxSetup to send AntiForgeryToken but even that didn't work.
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
var verificationToken = $("meta[name='__RequestVerificationToken']").attr('content');
if (verificationToken) {
jqXHR.setRequestHeader("X-Request-Verification-Token", verificationToken);
}
});
How can I overcome this issue? What is actually happening here?
UPDATE:
I am using ajax to post the formdata to controller as below:
$.ajax({
url: url,
type: "POST",
dataType: 'json',
data: formData,
processData: false,
contentType: false,
success: function (data) {
}
});
#Html.AntiForgeryToken() generates a hidden input with name="__RequestVerificationToken" so to get the value you need (for the first form)
var verificationToken = $('#frmAlbumAdd [name=__RequestVerificationToken]').val();
and then you can append it to the FormData object using
formData.append('__RequestVerificationToken', verificationToken);
However, since you are using FormData, you can simply serialize all the form controls, including the token and file inputs using
var formdata = new FormData($('#frmAlbumAdd').get(0));
Refer this answer for more details
Can i suggest that you try the following:
$("form").on("submit", function (event) {
event.preventDefault();
var form = $(this);
$.ajax({
url: form.attr('action'),
type: "POST",
data: form.serialize(),
success: function (data) {
//your implementation
},
error: function (jqXhr, textStatus, errorThrown) {
alert("Error '" + jqXhr.status + "' (textStatus: '" + textStatus + "', errorThrown: '" + errorThrown + "')");
},
complete: function () {
//your implementation
}
});
});
This does not uses json as the datatype. Do you really need to use json i like you to take a look at this How can i supply an AntiForgeryToken when posting JSON data using $.ajax?