How to add Antiforgery protection to such asp.net-mvc application? - javascript

I have an old asp.net mvc project using JS. I need to add Cross-Site Request Forgery protection, but I don't know, how to implement it in my case.
Could somebody help me with this, please?
chtml-view:
#model WebGridResults<IndexingCollectionModel>
#{
ViewBag.Title = "Manage Collections";
Layout = "~/_Indexing.cshtml";
}
#section grid_options
{
<div class="km-grid-option-padding">
<ul class="inline pull-right">
<li>
<a id="kmid_removeSelected"
class="km-grid-option remove"
href="#Url.Action("DeleteSelected", "Indexing", new { Area = "Admin" })"
data-target="km_grid_body"
data-redirect="#Url.Action("ManageCollections", "Indexing", new { Area = "Admin" })"
data-actiontype="submit_selected"
data-message="Do you want to continue?"><i class="icon-remove"></i> Remove Selected</a>
</li>
</ul>
</div>
}
JS-part:
$("[data-actiontype='submit_selected']").bind("click",
function () {
var $this = $(this);
var message = $this.data("message");
KM.Ajax.ShowConfirmation({ title: "Warning", message: message }, function () {
var url = $this.attr("href");
var redirect = $this.data("redirect");
var targetId = $this.data("target");
var selected = [];
var SelectedItemsIds = GetSelectedItemsIds();
$.each(SelectedItemsIds, function (Key, Item) {
selected.push({ name: "selected", value: Item });
});
//THIS PART WAS ADDED BY ME *********
var token = $("input[name='__RequestVerificationToken']").val();
if(token !== undefined && token !== "")
selected.push({name: "__RequestVerificationToken", value: token});
//*****************
$.ajax({
type: "POST",
url: url,
data: selected,
success: function (result) {
if (typeof (result) == "object") {
var json = result || {};
if (json.Success) {
var $target = $("#" + targetId);
if( settings.fullPageLoad === true )
{
location.reload();
}
else
{
$target.load( redirect, function()
{
if( settings.reloadCallback )
{
settings.reloadCallback();
}
} );
}
}
}
},
dataType: "json",
traditional: true
});
});
return false;
});
Controller:
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult DeleteSelected(Guid[] selected)
{
try
{
_presenter.Delete(selected);
return Json(new { Success = true });
}
catch (Exception ex)
{
ModelState.AddModelError(ErrorRemoveSelected, ex.Message);
var errors = ModelState.ParseErrors();
return Json(new { Success = false, Errors = errors });
}
}
I've tried to add to request data (it is my part of code) in JS-function:
var token = $("input[name='__RequestVerificationToken']").val();
if(token !== undefined && token !== "")
selected.push({name: "__RequestVerificationToken", value: token});
Also I've added [ValidateAntiForgeryToken()] to controller method.
And it works, but only one time. When I try to perform the same action on the same page - it doesn't work.
What am I doing wrong?
Thank you in advanced!

Related

Show partial view model using Ajax - ASP.NET C# AJAX JQuery

I am looking to show a modal, I have my Modals as partial classes, so if you select the class .js-verify-songs it loads up the partial _VerifySong . If however there is an error, it should load up the error partial _ErrorMessage. And finally if you select .js-reject-song it should load _RejectSong partial.
Any idea how I would do this, please?
to show errors. Currently I have this in my Controller to handle errors:
public partial class SongsManagementController : BaseController
{
private const string NoDataFound = "No data found.";
private const string InvalidDataPosted = "Invalid data posted";
private const string InvalidRequest = "Invalid request.";
private const string VerificationFailedUnexpectedError = "The following song failed to verify due to an unexpected error, please contact RightsApp support.";
private const string ConcurrencyError = "The following song failed to verify as another user has since changed its details.";
[HttpPost]
[Route("VerifyNewSongs")]
[AuthorizeTenancy(Roles = "super,administrator")]
public async Task<ActionResult> VerifyNewSongs(List<VerifySongViewModel> verifySongViewModels)
{
// Not AJAX method - refuse
if (!Request.IsAjaxRequest())
return RedirectToAction("NewSongs", "SongsManagement");
if (verifySongViewModels.NullOrEmpty())
{
// return error;
return Json(new JsonBaseModel
{
success = false,
message = InvalidRequest,
data = null,
errors = new List<string>
{
InvalidDataPosted
}
});
}
foreach (var verifySong in verifySongViewModels)
{
if (verifySong.WorkId == default(Guid) || verifySong.RowVersion == default(Guid))
{
return Json(new JsonBaseModel
{
success = false,
message = InvalidDataPosted,
data = null,
errors = new List<string>
{
$"Invalid data posted for following song.",
$"Song Title: {verifySong.SongTitle}",
$"Song Id: {verifySong.UniqueCode}"
}
});
}
var work = await _artistAccountService.GetWorkGraphAsync(verifySong.WorkId, includeWriterAmendments: true);
if (work == default(WorkGraphModels.Work))
{
return Json(new JsonBaseModel
{
success = false,
message = NoDataFound,
data = null,
errors = new List<string>
{
$"No data found for following song.",
$"Song Title: {verifySong.SongTitle}",
$"Song Id: {verifySong.UniqueCode}"
}
});
}
if (work.VerifiedState != Domain.Enumerators.VerifiedStateType.NotVerified)
{
return Json(new JsonBaseModel
{
success = false,
message = NoDataFound,
data = null,
errors = new List<string>
{
$"Song already verified.",
$"Song Title: {verifySong.SongTitle}",
$"Song Id: {verifySong.UniqueCode}"
}
});
}
work.RowVersion = verifySong.RowVersion;
var workAndAmendment = new WorkGraphModels.WorkAndAmendment
{
Original = work,
Amendment = null
};
var verifiedState = await _artistAccountService.VerifyWorkGraphAsync(workAndAmendment, GetLoggedUserId());
if (!verifiedState.ValidationErrors.NullOrEmpty())
{
return Json(new JsonBaseModel
{
success = false,
message = NoDataFound,
data = null,
errors = new List<string>
{
VerificationFailedUnexpectedError,
$"Song Title: {verifySong.SongTitle}",
$"Song Id: {verifySong.UniqueCode}"
}
});
}
else if (!verifiedState.DatabaseErrors.NullOrEmpty())
{
if (!verifiedState.FatalException)
{
// concurrency exception
return Json(new JsonBaseModel
{
success = false,
message = NoDataFound,
data = null,
errors = new List<string>
{
ConcurrencyError,
$"Song Title: {verifySong.SongTitle}",
$"Song Id: {verifySong.UniqueCode}"
}
});
}
else
{
// fatal
return Json(new JsonBaseModel
{
success = false,
data = null,
errors = new List<string>
{
VerificationFailedUnexpectedError,
$"Song Title: {verifySong.SongTitle}",
$"Song Id: {verifySong.UniqueCode}"
}
});
}
}
}
return Json(new JsonBaseModel
{
success = true,
message = "All songs verified successfully."
});
}
};
}
This is my Main View:
Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_SentricLayout.cshtml";
var actionName = ViewContext.RouteData.Values["Action"].ToString();
#* calc full account code *#
var fullAccountCode = Model.WorkUniqueCode;
ViewBag.Title = "New Songs";
}
#section scripts {
#Scripts.Render("~/bundles/jqueryajaxval")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/datetimepicker")
<script language="javascript" type="text/javascript">
#* DOM ready? *#
$(function () {
addTableStylingScripts();
var selectFormDiv = $('.catalogSelector');
selectFormDiv.hide();
$(".records-selected").hide();
// clear all filter boxes and reset search.
$("#btnClear").click(function()
{
$("#newSongsSearch").find(':input').each(function ()
{
if (this.type === "text")
{
$(this).val("");
}
});
$("#btnSearch").click();
});
#* edit catalogue button *#
$('#changeCat').click(function () {
$('#errorContainer').hide();
var label = $('#catLabel');
if (label.is(":visible")) {
label.hide();
selectFormDiv.show();
$('#changeCat').addClass("active");
} else {
label.show();
selectFormDiv.hide();
$('#changeCat').removeClass("active");
}
});
#* edit dropdown *#
$("#catalogueSelect").on("change", function () {
#* change display on select change *#
$('#errorContainer').hide();
$('#catLabel').show();
selectFormDiv.hide();
$('#changeCat').removeClass("active");
#* set up ajax post to controller *#
var model = {
AccountCode: '#fullAccountCode',
CurrentAccountId: $('#currentAccountId').val(),
CurrentRowVersion: $('#currentRowVersion').val(),
NewCatalogueId: $('#catalogueSelect option:selected').val(),
Action: '#actionName'
};
$.ajax({
url: '#Url.Action("ChangeCatalogue", "ArtistAccount")',
data: JSON.stringify(model),
type: 'POST',
cache: false,
contentType: 'application/json',
success: function (result) {
#* ajax worked *#
if (result.ChangeStatus === "Success")
{
var newSelected = $('#catalogueSelect option:selected').text();
$('#catLabel').html(newSelected);
#* update dropdown context *#
var newSelectedId = $('#catalogueSelect option:selected').val();
$('#currentCatalogue').val(newSelectedId);
#* update rowversion *#
var newRowVersion = result.OldOrNewRowVersion;
$('#currentRowVersion').val(newRowVersion);
}
else
{
$('#errorContainer').show();
$('#errorMessage').html(result.ErrorMessage);
#* return downdown context *#
var currentCatId = $('#currentCatalogue').val();
$("#catalogueSelect").val(currentCatId);
$('#catalogueSelect').select2({ width: '180px', dropdownAutoWidth: true });
}
},
error: function () {
#* failed *#
$('#errorContainer').show();
$('#errorMessage').html('There was a server error, please contact the support desk on (+44) 0207 099 5991.');
#* return downdown context *#
var currentCatId = $('#currentCatalogue').val();
$("#catalogueSelect").val(currentCatId);
$('#catalogueSelect').select2({ width: '180px', dropdownAutoWidth: true });
}
});
});
function loadPartialPage(url) {
$('.spinnerOverlay').removeClass('hide');
$.ajax({
url: url,
type: 'GET',
cache: false,
success: function (result) {
$('.spinnerOverlay').addClass('hide');
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
}
function getSelectedWorks() {
var selectedWorks = $(".individual:checked");
var works = [];
$.each(selectedWorks, function (key, value) {
works.push(getSelectedWork(this));
});
return works;
}
// verify songs in bulk
$(document).on("click", ".js-verify-songs", function (e) {
e.preventDefault();
var works = getSelectedWorks();
verifySongs(works);
});
// reject songs in bulk
$(document).on("click", ".js-reject-songs", function (e) {
e.preventDefault();
var works = getSelectedWorks();
});
function getSelectedWork(element) {
var work = new Object();
work.WorkId = getRowData(element, "id");
work.RowVersion = getRowData(element, "rowversion");
work.UniqueCode = getRowData(element, "uniqueworkid");
work.SongTitle = getRowData(element, "songtitle");
return work;
}
// verify one song
$(document).on("click", ".js-verify-song", function (e) {
e.preventDefault();
var works = [];
works.push(getSelectedWork(this));
verifySongs(works);
});
// reject one song
$(document).on("click", ".js-reject-song", function (e) {
e.preventDefault();
var works = [];
works.push(getSelectedWork(this));
});
function verifySongs(songs) {
$('.spinnerOverlay').removeClass('hide');
$.ajax({
url: '#Url.Action("VerifyNewSongs", "SongsManagement")',
data: JSON.stringify(songs),
type: 'POST',
cache: false,
contentType: 'application/json',
success: function (result) {
$('.spinnerOverlay').addClass('hide');
if (result.success) {
loadPartialPage($(".paginate_button.active a").attr("href"));
}
},
error: function(error) {
$('.spinnerOverlay').addClass('hide');
}
});
}
#* Pagination Async Partial Handling *#
$(document).on("click",
"#indexPager a",
function() {
if ($(this).parent().hasClass('disabled') || $(this).parent().hasClass('active'))
return false;
loadPartialPage($(this).attr("href"));
return false;
});
$(document).on("change",
"#pageSizeSelector",
function() {
var selectedValue = $(this).val();
loadPartialPage(selectedValue);
return false;
});
#* Sorting Async Partial Handling *#
$(document).on("click",
"#tableHeader a",
function()
{
loadPartialPage($(this).attr("href"));
return false;
});
});
// Ensure that after paging and sorting ajax calls we re-bind
// the change event and hide the record count label.
$(document).ajaxComplete(function() {
$(".records-selected").hide();
$(".individual").on("change", determineActionButtonAvailability);
$(".selectall").click(function () {
$(".individual").prop("checked", $(this).prop("checked"));
determineActionButtonAvailability();
});
});
// Search functions
$('.searchDivider').click(function (e) {
$('#searchFields').slideToggle();
var isSearchShown = $(this).find('.caret').hasClass("caret-up");
if (isSearchShown) {
$(this).children('span').replaceWith('<span class="bg-white">Search <b class="caret"></b></span>');
} else {
$(this).children('span')
.replaceWith('<span class="bg-white">Search <b class="caret caret-up"></b></span>');
}
});
$(".searchArea input:text").keypress(function (e) {
if (e.which === 13) {
e.preventDefault();
$("#btnSearch").click();
}
});
$(window).resize(function () {
if ($(window).width() >= 1024) {
$('#searchFields').show();
}
});
$(".searchArea input:text").keypress(function (e) {
if (e.which === 13) {
e.preventDefault();
$("#btnSearch").click();
}
});
// Checks individual checkboxes and displays the count
$(".individual").on("change", determineActionButtonAvailability);
$(".selectall").click(function () {
$(".individual").prop("checked", $(this).prop("checked"));
determineActionButtonAvailability();
});
//Disable Top Verify Button if two or more checkboxes are selected.
$('.verify-btn').prop('disabled', true);
//Disable Action Button in the columns when more than one checkbox is selected
$('.table-btn').prop('disabled', false);
$(".individual").on("click", function () {
if ($(".individual:checked").length > 1) {
$('.table-btn').prop('disabled', true);
$('.verify-btn').prop('disabled', false);
}
else {
$('.table-btn').prop('disabled', false);
$('.verify-btn').prop('disabled', true);
}
});
// When one or more works are selected, will enable the top action menu.
// Will disable when none selected.
function determineActionButtonAvailability() {
if ($(".individual:checked").length > 1) {
$(".records-selected").show();
$("#selected").text($(".individual:checked").length);
$("#total").text($(".individual").length);
$(".verify-btn").prop('disabled', false);
if ($(".individual:checked").length > 1) {
}
}
else {
$(".records-selected").hide();
$('.table-btn').prop('disabled', false);
$(".verify-btn").prop('disabled', true);
}
}
// Enforce only numeric input in the Unique Id search textbox.
$(document).on("keydown", ".uniqueCodefield", function (e) {
var key = window.event ? e.keyCode : e.which;
var currentVal = $('.uniqueCodefield').val();
if (key === 8 || key === 9 || key === 13 || key === 37 || key === 39 || key === 35 || key === 36 || key === 46) {
return true;
} else if (key === 13) {
$('#newSongsSearch').validate();
if ($('#newSongsSearch').valid()) {
return true;
}
return false;
}
else if ((key < 48 || key > 57) && (key < 93 || key > 105)) {
return false;
} else if (currentVal.length >= 10) {
return false;
} else {
return true;
}
});
#* Wire up the Search button click to perform an AJAXified search *#
$(document).on("click", "#btnSearch", function (e) {
e.preventDefault();
// Only perform the search if the search criteria is valid.
if (!$('#newSongsSearch').valid()) {
return false;
}
$('.spinnerOverlay').removeClass('hide');
var model = {
SearchModel: {
WorkUniqueCode: $('#SongCode').val(),
SongTitle: $('#SongTitle').val(),
CatalogueUniqueCode: $('#CatalogueCode').val(),
CatalogueName: $('#CatalogueName').val(),
AccountUniqueCode: $('#AccountCode').val(),
AccountName: $('#AccountName').val()
}
};
$.ajax({
url: '#Url.Action("SearchNewSongs", "SongsManagement")',
data: JSON.stringify(model),
type: 'POST',
cache: false,
contentType: 'application/json',
success: function (result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
return false;
});
#* Wire up the Search button click to perform an AJAXified search *#
$(document).on("click", "#btnSearch", function (e) {
e.preventDefault();
$('.spinnerOverlay').removeClass('hide');
var model = {
SearchModel : {
Name: $('#ContractNameSearch').val(),
ContractType: $('#ContractTypeSearch').val(),
CreatedBy: $('#CreatedBySearch').val(),
DateFrom : $('#DateFromSearch').val(),
DateTo : $('#DateToSearch').val()
}
};
$.ajax({
url: '#Url.Action("SearchContracts", "ClientSetup")',
data: JSON.stringify(model),
type: 'POST',
cache: false,
contentType: 'application/json',
success: function (result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
return false;
});
</script>
#Scripts.Render("~/bundles/searchusers-autosuggest")
}
#section additionalStyles {
#Styles.Render("~/plugins/datatables/media/css/cssDatatables")
}
<article class="row">
<h1 class="pageTitle artistHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-12">
<div class="panel panel-visible">
#Html.Partial("_NewSongsSearch", Model)
</div>
</div>
<div class="col-md-12">
<div class="panel panel-visible" id="tableContainer">
#Html.Partial("_NewSongsList", Model)
</div>
</div>
</article>
I am unsure though how I would show a list of error in my error partial view. Also how do you load a partial view with Ajax?
Currently you click verify and it loads the spinner, but I would like to load a partial view which is a modal. I’ve used partials because it’s what was decided. I’m just unsure how to get them to load using Ajax.

AJAX call in external JavaScript file not reaching ActionResult in controller

I am trying to check if an email address exists in the database. I have an external JavaScript file that I am using to call my jQuery (to keep my view clean). Perhaps it is because I am running with SSL enabled? (I am using https)
Function in external js file:
function checkemail() {
var email = $("#email").val();
$.ajax({
url: "/Account/CheckEmailExists/",
data: JSON.stringify({ p: email }),
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
alert(data)
}
});
}
Action in Controller:
public ActionResult CheckEmailExists(string p)
{
bool bEmailExists = false;
using (RBotEntities EF = new RBotEntities())
{
var query = (from U in EF.AspNetUsers
where U.Email == p
select U).FirstOrDefault();
if(query.Email != null)
{
bEmailExists = true;
}
else
{
bEmailExists = false;
}
}
return Json(bEmailExists, JsonRequestBehavior.AllowGet);
}
I seem to be getting an error stating the following:
XML Parsing Error: no root element found Location:
https://localhost:44347/Account/CheckEmailExists/ Line Number 1,
Column 1:
My understanding would be that this ActionResult does not exist. But it does ?
Am I doing something wrong, or is there a reason why an ActionResult can not be called via an external JavaScript file ?
Try this
In Controller
[httppost]
public ActionResult CheckEma.........
In JS
function checkemail() {
var email = $("#email").val();
$.ajax({
url: "/Account/CheckEmailExists/",
data: { p: email },
type: "POST",
success: function (data) {
alert(data)
}
});
}
No need for Json.Stringify and ContentType here
function checkemail() {
var email = $("#email").val();
$.ajax({
url: "/Account/CheckEmailExists",
data: { p: email },
type: "POST",
success: function (data) {
alert(data)
}
});
}
So I found out what was causing the issue...
Above my Action result, I needed to add [AllowAnonymous] data annotation and then it reached my ActionResult! I would prefer to not allow anonymous, but it works and I wanted to share this in case it helps someone else. Below is my code:
ActionResult:
[AllowAnonymous]
public ActionResult CheckEmailExists(string p)
{
bool bEmailExists = false;
using (RBotEntities EF = new RBotEntities())
{
var query = (from U in EF.AspNetUsers
where U.Email == p
select U).FirstOrDefault();
if (query.Email != null)
{
bEmailExists = true;
}
else
{
bEmailExists = false;
}
}
return Json(bEmailExists, JsonRequestBehavior.AllowGet);
}
JavaScript function in JavaScript File:
function checkemail() {
var email = $("#email").val();
var bReturnedValue = false;
$.ajax({
url: "/Account/CheckEmailExists/",
data: { p: email },
async: false,
success: function (data) {
if(data)
{
bReturnedValue = true;
}
else
{
bReturnedValue = false;
}
}
});
return bReturnedValue;
}
And this is how I initiated it(I am doing a popover to specify that the email exists):
$("#createacc_next").click(function () {
var bEmailExists = false;
bEmailExists = checkemail();
if (bEmailExists) {
$("#email").attr("disabled", false).css("border-color", "red");
$('#email').popover({ title: 'Attention', content: 'Email address already exists', placement: 'top', trigger: 'focus' });
Email_Validation_Passed = false;
}
})

Show Json Data after pushing Enter instead of Click ob submit

I have a MVC view that by clicking on submit button it post Data using Ajax to the Controller. The controller return json result that is messages and I show them on the View. The problem is when I click on Submit button it working fine but when I push Enter after show the Thank you page again it post to the controller method and show a page with json Data as bellow: (I need to make the Enter work as pushing Submit as well)
{"status":"success","message":""}
This is my View:
#using (Html.BeginForm("forgotPassword", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div>
<div>Email Address</div>
<div><input type="email" name="email" placeholder="example#email.com" id="email" class="forgot-password-textbox"></div>
<div><label id="Message" class="forgot-password-error-message"></label></div>
<div><input type="button" value="Submit" id="btn-reset-password" onclick="resetPasswordHandler()" class="orange-button forgot-password-button"></div>
</div>
}
This is my Controller Method:
[HttpPost]
[Route("forgotPassword")]
public async Task<JsonResult> ForgotPassword(ForgotPasswordRequest forgotPasswordRequest)
{
...
try
{
if (ModelState.IsValid)
{
if (!string.IsNullOrEmpty(forgotPasswordRequest.Email))
{
users = await authenticationService.GetUserByEmailAsync(forgotPasswordRequest.Email);
if (users.Any())
{
if(users.FirstOrDefault().StatusId == 2)
{
return Json(new { status = "error", message = Constants.MessageStrings.ForgotPasswordDisabledUser });
}
//New User without creating password
if (string.IsNullOrEmpty(users.FirstOrDefault().PasswordHash))
{
return Json(new { status = "error", message = Constants.MessageStrings.ForgotPasswordDisabledUser });
}
....
}
}
else
{
ModelState.AddModelError("", Constants.MessageStrings.NoUser);
return Json(new { status = "error", message = Constants.MessageStrings.NoUser });
}
}
}
else
{
.......
return Json(new { status = "error", message = Constants.MessageStrings.RequiredFields });
}
and this is my Ajax to call controller:
function resetPasswordHandler() {
var postResult = null;
var data = {
Email: document.getElementById('email').value
};
var path = "/forgotPassword";
var errorMessage = document.getElementById('Message');
$.ajax({
dataType: "text",
url: path,
data: data,
type: "POST",
cache: false,
success: function (result) {
postResult = $.parseJSON(result);
if (postResult.status == "success") {
$('#forgot').hide();
$('#forgot-thank-you').show();
return false;
}
else {
errorMessage.innerHTML = postResult.message;
}
},
error: function () {
errorMessage.innerHTML = "An error occured";
}
});
return false;
};
window.onkeydown = function () {
if (window.event.keyCode == '13') {
resetPasswordHandler();
}
}
return Json(new { status="success",message="what ever your msg"}, JsonRequestBehavior.AllowGet);
I would remove the click handler from the button, and handle the submit event of the relevant form.
You should give an id for easier targeting
#using (Html.BeginForm("forgotPassword", "Home", FormMethod.Post, new { id = "reset-form" }))
And simplify your script (since you are using jQuery) to
function resetPasswordHandler(event) {
var postResult = null,
data = {
Email: $('#email').val()
},
path = "/forgotPassword",
errorMessage = $('#Message');
event.preventDefault();
$.ajax({
dataType: "text",
url: path,
data: data,
type: "POST",
cache: false,
success: function(result) {
postResult = $.parseJSON(result);
if (postResult.status == "success") {
$('#forgot').hide();
$('#forgot-thank-you').show();
return;
} else {
errorMessage.html(postResult.message);
}
},
error: function() {
errorMessage.html("An error occured");
}
});
return false;
};
$('#reset-form').on('submit', resetPasswordHandler);

getting anonymous function error in ajax

I call the Ajax to get the result from web API in my MVC project. in my local the page works but in production it is not working and giving me this error in .js file exactly at this line: $.ajax
http://mylink.cloudapp.azure.com/searchuser 404 (Not Found)
x.extend.ajax anonymous function
This is my .js file:
$(document).ready(function () {
$('#btnSearch').click(function (evt) {
// debugger;
if (ValidateInput()) {
var data = {
LastName: $.trim($('#LastName').val() || ''),
Zip: $.trim($('#Zip').val() || ''),
Ssn: $.trim($('#Ssn').val() || '')
};
var token = $('[name=__RequestVerificationToken]').val();
$.ajax({
dataType: "json",
//headers: { "__RequestVerificationToken": token },
data: data,
url: '/searchuser',
type: 'POST',
cache: false,
success: function (result) {
console.log(result);
if (result && result.success) {
$('#ApplicationId').val(result.data.applicantId);
if (result.data.exception == null) {
$('#stepTwo').show();
$('#EmailAddress').val(result.data.userEmailAddress);
}
else {
$('#txtareaResponse').val(result.data.exception);
}
}
},
error: function () { debugger; alert('failure'); }
});
}
});
and this is top of my view:
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<link href="~/Content/Loan.css" rel="stylesheet" />
<script src="~/Scripts/Verify.js"></script>
and this is the controller method:
[AllowAnonymous]
[Route("searchuser")]
[HttpPost]
public async Task<ActionResult> SearchUser(UserInfo userInfo)
{
object userObject = null;
if (userInfo.LastName != null && userInfo.Zip != null && userInfo.Ssn != null)
{
string accessKey = CreateAccountKey(userInfo.LastName, userInfo.Zip, userInfo.Ssn);
UserKey userKey = new UserKey();
userKey.AccountKey = accessKey;
//var response = await httpClient.GetAsync(string.Format("{0}{1}/{2}", LoanApiBaseUrlValue, "/verifyuser", accessKey));
var response = await httpClient.PostAsJsonAsync(string.Format("{0}{1}", LoanApiBaseUrlValue, "/verifyuser"), userKey);
if (response.IsSuccessStatusCode)
{
userObject = new JavaScriptSerializer().DeserializeObject(response.Content.ReadAsStringAsync().Result) as object;
var json = response.Content.ReadAsStringAsync().Result;
var userVerify = new JavaScriptSerializer().Deserialize<VerifyUser>(json);
}
}
var respone = new
{
success = userObject != null,
data = userObject
};
return Json(respone, JsonRequestBehavior.AllowGet);
}
Try just returning an ActionResult
[AllowAnonymous]
[Route("searchuser")]
[HttpPost]
public ActionResult SearchUser(..){..}
also in your ajax call use the Razor syntax
$.ajax({
url: "#Url.Action("method", "Controller")",
type: "GET",
data: {},
success: function (data) {
//do stuff...
}
});

Does jQuery.ajax() not always work? Is it prone to miss-fire?

I have an $.ajax function on my page to populate a facility dropdownlist based on a service type selection. If I change my service type selection back and forth between two options, randomly the values in the facility dropdownlist will remain the same and not change. Is there a way to prevent this? Am I doing something wrong?
Javascript
function hydrateFacilityDropDownList() {
var hiddenserviceTypeID = document.getElementById('<%=serviceTypeID.ClientID%>');
var clientContractID = document.getElementById('<%=clientContractID.ClientID%>').value;
var serviceDate = document.getElementById('<%=selectedServiceDate.ClientID%>').value;
var tableName = "resultTable";
$.ajax({
type: 'POST',
beforeSend: function () {
},
url: '<%= ResolveUrl("AddEditService.aspx/HydrateFacilityDropDownList") %>',
data: JSON.stringify({ serviceTypeID: TryParseInt(hiddenserviceTypeID.value, 0), clientContractID: TryParseInt(clientContractID, 0), serviceDate: serviceDate, tableName: tableName }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
a(data);
}
,error: function () {
alert('HydrateFacilityDropDownList error');
}
, complete: function () {
}
});
}
function a(data) {
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
var tableName = "resultTable";
if (facilityDropDownList.value != "") {
selectedFacilityID = facilityDropDownList.value;
}
$(facilityDropDownList).empty();
$(facilityDropDownList).prepend($('<option />', { value: "", text: "", selected: "selected" }));
$(data.d).find(tableName).each(function () {
var OptionValue = $(this).find('OptionValue').text();
var OptionText = $(this).find('OptionText').text();
var option = $("<option>" + OptionText + "</option>");
option.attr("value", OptionValue);
$(facilityDropDownList).append(option);
});
if ($(facilityDropDownList)[0].options.length > 1) {
if ($(facilityDropDownList)[0].options[1].text == "In Home") {
$(facilityDropDownList)[0].selectedIndex = 1;
}
}
if (TryParseInt(selectedFacilityID, 0) > 0) {
$(facilityDropDownList)[0].value = selectedFacilityID;
}
facilityDropDownList_OnChange();
}
Code Behind
[WebMethod]
public static string HydrateFacilityDropDownList(int serviceTypeID, int clientContractID, DateTime serviceDate, string tableName)
{
List<PackageAndServiceItemContent> svcItems = ServiceItemContents;
List<Facility> facilities = Facility.GetAllFacilities().ToList();
if (svcItems != null)
{
// Filter results
if (svcItems.Any(si => si.RequireFacilitySelection))
{
facilities = facilities.Where(f => f.FacilityTypeID > 0).ToList();
}
else
{
facilities = facilities.Where(f => f.FacilityTypeID == 0).ToList();
}
if (serviceTypeID == 0)
{
facilities.Clear();
}
}
return ConvertToXMLForDropDownList(tableName, facilities);
}
public static string ConvertToXMLForDropDownList<T>(string tableName, T genList)
{
// Create dummy table
DataTable dt = new DataTable(tableName);
dt.Columns.Add("OptionValue");
dt.Columns.Add("OptionText");
// Hydrate dummy table with filtered results
if (genList is List<Facility>)
{
foreach (Facility facility in genList as List<Facility>)
{
dt.Rows.Add(Convert.ToString(facility.ID), facility.FacilityName);
}
}
if (genList is List<EmployeeIDAndName>)
{
foreach (EmployeeIDAndName employeeIdAndName in genList as List<EmployeeIDAndName>)
{
dt.Rows.Add(Convert.ToString(employeeIdAndName.EmployeeID), employeeIdAndName.EmployeeName);
}
}
// Convert results to string to be parsed in jquery
string result;
using (StringWriter sw = new StringWriter())
{
dt.WriteXml(sw);
result = sw.ToString();
}
return result;
}
$get return XHR object not the return value of the success call and $get function isn't synchronous so you should wait for success and check data returned from the call
these two lines do something different than what you expect
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
change to something similar to this
var facilityDropDownList;
$.ajax({
url: '<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>',
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
facilityDropDownList= data;
}
});

Categories

Resources