Ajax not making function call - c#

I have ajax function as:
function LoadTeacherObservationData(_CategoryID, _SearchText) {
alert("In here");
alert(_CategoryID);
alert(_SearchText);
flag = 1;
$.ajax({
url: "PP/getTeacherObservationData",
data: {
'CategoryID': _CategoryID,
'SearchText': _SearchText
},
dataType: "json",
type: 'POST',
cache:false,
success: function (data) {
OnlebelChange(_CategoryID);
$('#hdnCategoryID').val(_CategoryID);
$("#lvTeacherData").kendoListView({
dataSource: data,
dataBound: function(e) {
if(this.dataSource.data().length == 0){
//custom logic
$("#lvTeacherData").append("<h4> No record found.</h4>");
}},
template: kendo.template($("#lvTeacherData_Template").html())
});
},
error: function () {
alert("error in click");
}
});
}
I have made sure that function is getting called with correct parameters as i have checked it through alert box.
My problem is its not getting rendered to:
PP/getTeacherObservationData as i have mentioned in URL.
PP is my controller and getTeacherObservationData is my function.
I have written that function as follows:
public JsonResult getTeacherObservationData(string CategoryID, string SearchText)
{
try
{
if (CategoryID == "1")
return Json(new TeacherObservation().ScheduledObserVations(SearchText));
if (CategoryID == "2")
return Json(new TeacherObservation().InProcessObservations(SearchText));
if (CategoryID == "3")
return Json(new TeacherObservation().CompletedObservations(SearchText));
return Json(new List<TeacherObservation>());
}
catch (Exception ex)
{
throw ex;
}
}
Instead of calling this function ajax function code goes in error block and gives me alert as: error in click
What can be the problem??
Please help me.
I want to make function call through ajax.
Using MVC4.

Expanding on my comment: the URL PP/getTeacherObservationData is relative so if you are currently not in the root of the site, then this won't work.
Using a forward slash prefix /PP/getTeacherObservationData will work if your site is in the root of the domain.
You could also use one of the solutions in this answer. Such as ResolveUrl("~/") to dynamically get the site's root, which is better because it's more portable. For example if you move your site out of the domain's root and into a directory, this will continue to work unlike hard coding the root.

I don't know what PHP Framework you are using, but normally you can't just return a value to an AJAX call, you have to ouput it somehow to send it back to the caller. Try to use echo or print instead of return.
To prevent further rendering (if any), you should somehow end the script after it has echoed your specified JSON.
You should also check for the output that is rendered in firebug or similar consoles to see if you get a plain JSON (which you obvoiously expect) or some HTML wrapped content which is rendered by your php framework and connot be parsed.

Related

How to call C# method from Javascript in ASP.NET Core?

I have a username textbox in my Index.cshtml file and I want to check for matches in our Active Directory whenever the user changes the text inside the textbox and then maybe display it in a DropDownList, so the user can choose form it.
So I call a JavaScript function on the oninput event of the textbox and now the question is how do I call my C# method FindUser() in Index.cshtml.cs from that JS function? I have tried a lot of what I've read, ajax call doesn't work, adding [WebMethod] and making the method static doesn't work and most on the internet is on MVC which I'm not using.
Textbox in Index.cshtml:
<input type="text" class="form-control" oninput="findUsers()" />
JavaScript function:
function findUsers() {
$.ajax({
url: 'Index\FindUser',
success: function (data) {
alert(data);
},
error: function (error) {
alert("Error: " + error);
}
})
}
leads the browser to alert
Error: [object Object]
Method in Index.cshtml.cs:
public void FindUser()
{
// code
}
The method is not even called from the JS function.
Also I've read a few times that calling a C# method from the view is not the proper way of doing it. If so, how can I achieve my goal then?
I see you're using Razor pages. A method in razor page model is not a routed method (it can't be called by requesting a route), and that's why trying to send an ajax request to Index\FindUser won't work, and the error returned by server would be 404 not found.
Alternatively you can use razor page handlers.
In your Index.cshtml.cs rename the method FindUser() to OnGetFindUser() or OnGetFindUserAsync() if the method is an asynchronous method.
You can then call this method by sending a request to "Index?handler=FindUser".
// Note the difference in method name
public IActionResult OnGetFindUser()
{
return new JsonResult("Founded user");
}
function findUsers() {
$.ajax({
type: 'GET',
// Note the difference in url (this works if you're actually in Index page)
url: '?handler=FindUser',
success: function (data) {
alert(data);
},
error: function (error) {
alert("Error: " + error);
}
})
}
Further suggested read
I am not very experienced yet, I have only started programming last year, but I hope I can help a little bit.
I also had a similar problem, but I could not execute a function directly from JavaScript. You could maybe create an API call to C# and make the API execute the function you want, and then return the data back to the client.
If I don't misunderstand, you want the user to type some text, and then return from your database a list based on the typed text.
You could use an onChange in the input tag, and each time it changes, it executes an API request to the server, which will search whatever you need and return it as a json. Then in JavaScript, you parse the data and put it in a select tag.
Hope it helps.
Ok so first off, you are calling jquery inside javascript function.
Calling a controller action method from ajax is pretty easy.
https://api.jquery.com/jquery.ajax/
You need to determine the request type, the url, the datatype returned, parameters passing etc and then set a breakpoint on the controller action and on the ajax request success and error functions. Then you will be able to see why it has succeeded or failed.
The way i would do it would be to give the input an id, then when a user types text catch the event.
https://api.jquery.com/category/events/
Don't confused jquery and javascript.
Jquery is a framework that packs javascript inside it.
Javascript is the native language.
You can use onkeyup or onblur like this
onblur: When you leave the input field, a function is triggered
onkeyup: A function is triggered when the user releases a key in the
input field
Then modify your code like this
html file:
<input type="text" class="form-control" id="username" oninput="findUsers()" />
js
function findUsers() {
var username= document.getElementById("username").value;
$.ajax({
type: 'GET',
url: '/Home/FindUser
dataType: 'json',
data: {username},
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
}
});
}
You must return something like this. You are using void keyword so it will not return anything to FE side
public JsonResult FindUser(string username)
{
var object = {
// something here
}
return Json(object);
}
Change your API like this:
public bool FindUser(string value)
{
if (value == "Joe")
return true;
else
return false;
}
Then call it like this:
<script type="text/javascript">
function findUsers() {
var value = document.getElementById("value").value;
$.ajax({
type: 'GET',
url: '/Home/FindUser,
data: value,
dataType: 'json',
success: function (data) {
alert(data);
},
error: function (error) {
alert(error);
}
});
}
</script>
<br />
<input type="text" class="form-control" id="value" oninput="findUsers()" />
you can call method exactly you want with
small addition to Index.cshtml. First line may be:
#page "{handler?}"
then call from ajax:
url:'/index/FindUser'
in Index.cshtml.cs calling method:
void OnGetFindUser(){}

Server result to webpage

I am trying to simply write out some data to my webpage as a result of a callback. Everything works up until the point where I need to output the result of the callback.
Client-side:
function toServer(data) {
var dataPackage = data + "~";
jQuery('form').each(function () {
document.getElementById('payload').value = JSON.stringify({ sendData: dataPackage });
$.ajax({
type: "POST",
async: true,
url: window.location.href.toString(),
data: jQuery(this).serialize(),
success: function (result) {
//this does not work because it just puts an entire source code copy of my site in there instead...
//document.getElementById('searchResults').value = result
console.log("callback compelete");
},
error: function(error) {
console.log("callback Error");
}
});
});
}
Server-Side: (on page load)
//holds actions from page
string payload = HttpContext.Current.Request.Form["payload"] ?? String.Empty;
// See if there were hidden requests (callbacks)
if (!String.IsNullOrEmpty(payload))
{
string temp_AggregationId = CurrentMode.Aggregation;
string[] temp_AggregationList = temp_AggregationId.Split(' ');
Perform_Aggregation_Search(temp_AggregationList, true, Tracer);
}
else
{
HttpContext.Current.Session["SearchResultsJSON"] = "";
}
The rest of the server-side code works properly and just handles the parsing of the incoming and performs a search of the db and then parses the search results into a JSON obj.
Currently, the only way the json obj gets written to the page is if I call it without the callback (just call it on page load). Also, in firebug, it looks like the entire page source is posting back as the 'result' of the callback. I do see my json result within the posted back 'result' but it also contains the entire page HTML.
Moreover, I can't seem to get the result to post to the page which is the whole point. Actually, I could get the result to post to the page by simply uncommenting that bit in the client side code but it posts a copy of my site and not the actual result I thought I created...
What am I missing? How do you explicitly state in the C# code what is returned to the JS callback as 'result'?
You get the entire page because you're making a request to an ASP.NET page. In fact, you're requesting the vary same page you're viewing. The server is returning what it would return if you were submitting a form.
To get JSON data, you need to create a web method to handle your request. Read this article, it will help you. It shows you how to return simple text, but you can return JSON too. Information on this MSDN article.
Finally, to make sure jQuery is parsing the server response as JSON, change your request and indicate it explicitly:
function toServer(data) {
var dataPackage = data + "~";
jQuery('form').each(function () {
document.getElementById('payload').value = JSON.stringify({ sendData: dataPackage });
$.ajax({
type: "POST",
async: true,
url: window.location.href.toString(),
data: jQuery(this).serialize(),
dataType: 'json',
success: function (result) {
//this does not work because it just puts an entire source code copy of my site in there instead...
//document.getElementById('searchResults').value = result
console.log("callback compelete");
},
error: function(error) {
console.log("callback Error");
}
});
});
}

MVC3. Browser alerts by itself when returning 500 status code

Hello how to prevent browser from alerting by itself, when returning a HttpStatusCodeResult object.
The Action Method:
[HttpPost]
public ActionResult Finish()
{
//Throw the status code result
return new HttpStatusCodeResult(500,"Oops something wrong happened!");
}
The script
jQuery.ajax({
url: '#Url.Action("Finish","Home")',
type: "POST",
success : function(result) {
alert("success is:"+result);
},
error: function (response, status, errorThrown) {
alert(errorThrown);
}
});
The result of calling Finish() Action is displayed in the alert(); function, but
under the custom alert,
The browser also alerts with a message - "The page cannot be displayed because an internal server error has occurred."
SOLUTION
The actual problem was, as #tanathos pointed out, a global function:
jQuery(document).ajaxError(function (e, jqxhr, settings, exception) {
if (jqxhr != null) {
alert(jqxhr.responseText);
}
Thank you very much for your help. Question Closed.
Maybe somewhere in your project there's already a lower level catch for ajax errors, like an ajaxSetup or an ajaxError.
Also, is jQuery the only framework implemented?

How to use custom AuthorizeAttribute with AJAX

With help of fellow friends I managed to find a solution for my problem from this topic: Reusable way to allow an account to be used by a single person at a time
I have a SingleLogin class which inherits from AuthorizeAttribute and implements a custom AuthorizeCore method for the purpose of re-usability of my single-login code:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool isAuthorized = base.AuthorizeCore(httpContext);
if (isAuthorized)
{
int userId = (int)WebSecurity.CurrentUserId;
using (var db = new UsersContext())
{
if ((httpContext.Session.SessionID != db.getSessionId(userId))
|| db.getSessionId(userId) == null)
{
WebSecurity.Logout();
isAuthorized = false;
httpContext.Response.Redirect("/Home/Index");
}
}
}
return isAuthorized;
}
Everything works fine except my JsonResult action:
[HttpPost]
public JsonResult MessageSave(string message)
{
bool messageSaved = false;
int userId = (int)WebSecurity.CurrentUserId;
message = HttpUtility.HtmlEncode(message);
// Model method - adding chat log - db
db.addChatLog(message, userId);
messageSaved = true;
return Json(new { messageSaved = messageSaved });
}
This method is triggered by Ajax POST call which you can see in code example below. Just basic POST.
EDIT 3
Please check these images: http://imgur.com/a/Cjael .. Hm I guess POST does trigger, but have no idea why does my alert not work when I try to test it before $.ajax ... As you can see in response I do get Home/Index page but I am not redirected to home/index immediately(text stays inside of textBox and page just waits..), I have to push enter one more time to be redirected.. Very strange.
EDIT2
Seems like I can't even access my jQuery even after I get logged out. I put some alerts inside of my .js file.
I have a separate .js file which is then put in my View as <script src="~/Scripts/custom/homeChat.js"></script> . I pass the Razor values from View into my JS file via HTML5 data-.
My textBox element #txtMsg, triggers my jQuery event, therefore when I am logged out it probably doesn't recognize my textBox element anymore, and doesn't trigger my jQuery event?
Element that triggers .js in view is:
#Html.TextBox("txtMsg")
JS:
$("#txtMsg").keypress(function (e) {
//when enter
if (e.which == 13) {
alert("ALERT DOESNT TRIGGER");
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({ message: input }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.messageSaved) {
$("#txtMsg").val("");
}
else {
window.location.href = urlhome;
}
}
});
}
}
});
So if you can't even come into your event, how can you even know something went wrong? I have this ˙HandleUnauthorizedRequest but you are required that you can get into your jQuery event(in my case .keypress in the js code above) for this to work if I understand right.
EDIT: Additional explanation
So let me explain the scenario. If I login with my username "john" from Firefox and again with username "john" from chrome, next action I do in Firefox, it will log me out and redirect me to Home/Index, because someone else made a new login in Chrome.
That is ok. Since you are not logged in anymore, you get redirected normally to your Home/Index if your action is normal ActionResult and returns view.
The problem I have is, that I have some other functionality in the page, which uses Ajax POST, and since you are logged out you can't POST to that JsonResult action therefore you can't even receive callback of error, which redirects you to Home/Index. I put some alerts into my JS, but no alert triggers which is normal, because I am not allowed on that page anymore anyway. If I want that my onEnter textbox redirects me to Home/Index I have to press enter twice. Is that all that could be done?
I am interested in best approach for this AJAX problem. I don't know how I should call it, but as I read from my previous topic it is called "handling AJAX timeouts"?
Thank you very much.
You can handle errors on AJAX request this way
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({ message: input }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data.messageSaved) {
$("#txtMsg").val("");
}
else {
window.location.href = urlhome;
}
},
error: function(xhr, status, error) {
// TODO: may be check error or status or xhr.statusCode()
window.location.href = urlhome;
}
});
jQuery $.ajax() docs
If understand it correctly you want to handle the unauthorized ajax request.
In that case you can override the HandleUnauthorizedRequest method in your attribute:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
filterContext.Result = new JsonResult();
}
else
{
filterContext.Result = new HttpStatusCodeResult((int)HttpStatusCode.Forbidden);
}
}

update field or redirect page using jquery and asp.net mvc

Im new to jquery and stuck with what i want to achieve.
Heres what I want to do using jquery and asp.net mvc.
click a submit button
this calls an action method called LogOn in the controller Account
if the call allows users to log in succesfully redirect to a url (sepecified by LogOn)
if it fails replace a div(with id="error") with "sorry error occured"
so far I tried this:
$("#submit")
.button()
.click(function () {
$.ajax({
type: "POST",
url: "Account/LogOn",
dataType: "json",
success: function (data, textStatus) {
if (data.redirect) {
// data.redirect contains the string URL to redirect to
window.location.href = data.redirect;
}
else {
// data.form contains the HTML for the replacement form
$("#error2").replaceWith(data.error);
}
}
});
});
how do I construct the relevant bits in the action method? to make this work?
and is the jquery code ok? i suspect prob not.
Thanks
If you want to redirect asp.net page at same directory , you can by Jquery/Java script by this :
$("#ctl00_iframecontent_BtnCancle").click(function () {
window.location = "IncSLAList.aspx?bi=37";
});
and
To redirect to Another page of project , can use :
window.location.href = "http://ImageUpload/Welcome.aspx?
Your jQuery is almost correct:
Don't call .button() (unless you're using jQuery UI and want to do that)
Add return false; at the end of the click handler to prevent the browser from submitting normally.
In the action, you would either return Json(new { redirect = str }) or return Json(new { error = str }).

Categories