I am trying to call a method from my aspx page. This method is found on the aspx.cs page, but it is throwing an error. Do you know what's wrong, please?
ajax script
<script type="text/javascript">
function OnSucceeded(response) {
alert(response);
}
function OnFailed(error) {
alert(error);
} //Default.aspx
function insertMarker() {
var usernameName = 'username';
var usernameVal = document.getElementById('<%=hdnUsername.ClientID%>').value;
var latitudeName = 'latitudeStr';
var latitudeVal = document.getElementById('<%=hdnMarkerLatitude.ClientID%>').value;
var longituteName = 'longitudeStr';
var longitudeVal = document.getElementById('<%=hdnMarkerLongitude.ClientID%>').value;
var iconName = 'markerIcon';
var iconVal;
if (document.getElementById('blueMarker').checked) {
iconVal = 'images/blueMarker.png';
}
if (document.getElementById('greenMarker').checked) {
iconVal = 'images/greenMarker.png'
}
if (document.getElementById('pinkMarker').checked) {
iconVal = 'images/pinkMarker.png';
}
var titleName = 'name';
var titleVal = document.getElementById('<%=title.ClientID%>').value;
var descriptionName = 'description';
var descriptionVal = document.getElementById('<%=description.ClientID%>').value;
$.ajax({
type: "POST",
url: "mapping.aspx/insertNewMarker",
data: {"username" : usernameVal, "longitudeStr":longitudeVal, "latitudeStr" :latitudeVal, "markerIcon":iconVal, "name" : titleVal, "description" :descriptionVal},
contentType: 'application/json; charset=utf-8',
dataType: 'json',
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + textStatus + "\n\nError: " + errorThrown);
},
success: function (result) {
alert("We returned: " + result.d);
}
});
}
</script>
Website Design
Save Marker
Title
Description
Save
Aspx.cs Method.
[ScriptService]
public partial class mapping: System.Web.UI.Page
{
[WebMethod]
private static void insertNewMarker(string username, string longitudeStr, string latitudeStr, string markerIcon, string name, string description)
{
//My Code
}
}
Your server-side webmethod cannot be private, you have to change it to public.
From MSDN documentation on webmethods:
When you create a Web service in managed code, you indicate the
methods that are available through that Web service by placing the
WebMethod attribute before the method declaration of a Public method.
Private methods cannot serve as the entry point for a Web service
although they can be in the same class and the Web service code can
call them.
Change your data like this
data:JSON.stringify({username : usernameVal, longitudeStr:longitudeVal, latitudeStr :latitudeVal, markerIcon:iconVal, name : titleVal, description :descriptionVal}),
You need to pass data as json stirng which has a specific format. If you use JSON.stringify data will be convetred to json string and if you don't use this than you have to pass every paremter and its value in quotes like this.
data:"{username:'" + usernameVal + "',............}",
Related
i have a script function that can call a web methods with two parameters.I want to call this script function from code behind.Here is my script function that i want to call from code behind.(I am using the .ascx usercontrol).
function BindApporment(obj, divid) {
debugger;
var username = "<%= Session["UserId"]%>";
var id = document.getElementById('<%=Hiddendocid.ClientID%>').value;
if (id != "") {
username = id;
}
$.ajax({
type: "POST",
url: "Dashboard.aspx/BindAppointment",
contentType: "application/json;charset=utf-8",
data: "{'date':'" + obj + "',userid:'" + username + "'}",
dataType: "json",
success: function (data) {
$(divid).html(data.d);
},
error: function (result) {
alert("Error ");
}
});
}
here is my web method
[WebMethod]
public static string BindAppointment(DateTime date, string userid)
{
}
...I want to call the script function BindApporment() from code behind..i have already tried a lot of code but this is not working..
I have tried these code but not working:
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "BindApporment", "<script>BindApporment(" + date.AddDays(k).Date + "," + ddldoc.SelectedValue + ");</script>");
any suggestions??
You are trying to do that is not applicable to to in ASP.NET structure. A ascx control cannot process request. The ASCX can work with the data send via postbacl
You need to create ASMX service and query it with ajax request you have. How to let an ASMX file output JSON
I am new to JS, even less experienced at AJAX. I'm just trying to pass a value to the code behind and return an expanded response.
The problem is that despite the call succeeding, the string value passed from AJAX to C# is never anything other than "undefined", and it is driving me insane.
The JS
function test() {
var message = "this is a test" ;
Display(message);}
function Display(words) {
var hummus = { 'pass': words};
$.ajax({
type: 'POST',
url: 'Account.aspx/ShowMe',
data: hummus,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (response) {
alert("Your fortune: " + response.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + words + "\n\nError: " + lion);
}
});}
The Code Behind
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ShowMe(string pass)
{
string beans = pass + ". We repeat this is only a test.";
return beans;
}
The end result is invariably "Your fortune: undefined. We repeat this is only a test."
I would only like to know what I am missing.
Yes this is probably a stupid question but my searches reveal nothing helpful.
Your issue is that you are trying to accept a string in your method public static string ShowMe(string pass) but you are passing a JavaScript object as your data. See when you make an Ajax call ASP.Net will do its best to match up the data you posted to the type you have in your parameter - called Model Binding. When this cannot be achieved then you get an null passed in.
So in your JavaScript you are passing a JavaScript object using this:
var hummus = { 'pass': words};
$.ajax({
....,
....,
data: hummus,
If you wish to post an object then your controller/method needs to have a C# model (class) that your JS will be bound to.
So change your method to accept a model:
// somewhere in your code put this little model
// this is what your JavaScript object will get bound to when you post
public MyModel{
// this is to match the property name on your JavaScript object, its case sensitive i.e { 'pass': words};
public string pass {get;set;}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ShowMe(MyModel model)
{
// you can now access the properties on your MyModel like this
string beans = model.pass + ". We repeat this is only a test.";
return beans;
}
I found two issues in your code -
Missing data: JSON.stringify(hummus),
Remove lion which variable doesn't exist.
Fix
function test() {
var message = "this is a test";
Display(message);
}
function Display(words) {
var hummus = { 'pass': words };
$.ajax({
type: 'POST',
url: 'Account.aspx/ShowMe',
data: JSON.stringify(hummus), // Missing JSON.stringify
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (response) {
alert("Your fortune: " + response.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// remove lion which variable doesn't exist.
alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + words);
}
});
}
Working code
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Account.aspx.cs" Inherits="WebApplication1.Account" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<button type="button" onclick="test()">Display Word</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
function test() {
var message = "this is a test";
Display(message);
}
function Display(words) {
var hummus = { 'pass': words };
$.ajax({
type: 'POST',
url: 'Account.aspx/ShowMe',
data: JSON.stringify(hummus), // Missing JSON.stringify
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (response) {
alert("Your fortune: " + response.d);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// remove lion which variable doesn't exist.
alert("Request: " + XMLHttpRequest.toString() + "\n\nStatus: " + words);
}
});
}
</script>
</form>
</body>
</html>
public partial class Account : System.Web.UI.Page
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ShowMe(string pass)
{
string beans = pass + ". We repeat this is only a test.";
return beans;
}
}
Thank you both for your help. I'm going to try the Model method, the JSON.stringify was something I had tried before and ultimately worked.
Apparently the problem I was not understanding how my browser worked. No matter what changes I made I was getting the same error. The reason?
My code wasn't in tags on the page, it was in a separate js file which Chrome was caching for me, effectively negating every change I made to try and correct the problem and driving me insane in the process.
In all I've learned a new technique, Model Binding, and that location of code can dramatically effect your Javascript experience.
A list of images (treasures) are displayed to the user, here the user will choose a single image which will be stored in the Learner_treauser table:
List<The_Factory_Chante.Models.Treasure> tresh;
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{
string imageSource = "";
tresh = db2.Treasures.ToList();
foreach (var item in tresh)
{
if (item.itemImage != null)
{
string imageBase = Convert.ToBase64String(item.itemImage);
imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
}
<img id="#item.treasureID" src="#imageSource" onclick="return MakeSure(#item.treasureID)" />
}
}
The function called when an image is chosen. In this function the image is sent over to a webservice method to be saved to the database, and the page is reload for an update to take place:
function MakeSure(treshID) {
var id = treshID
$.ajax({
url: "../../WebService.asmx/MakeSure",
data: "{ 'id': '" + id + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
window.location.reload();
};
However this is not very pleasant on the user's point of you. A better way would be to update without refreshing the page.
Here is the Webservice method that receives the chosen image id and stores it in the Learner_Treasure table.
public void MakeSure(int id)
{
using (The_FactoryDBContext db = new The_FactoryDBContext())
{
Learner_Treasure learnTreasure = new Learner_Treasure();
learnTreasure.dateCompleted = DateTime.Today;
learnTreasure.learnerID = UserInfo.ID;
learnTreasure.treasureID = id;
db.Learner_Treasure.Add(learnTreasure);
db.SaveChanges();
}
Code to call Learner_Treasure table.
List<The_Factory_Chante.Models.Learner_Treasure> lern;
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{
string imageSource = "";
lern = db2.Learner_Treasure.ToList();
if (lern != null)
{
foreach (var item in lern)
{
if (item.learnerID == UserInfo.ID)
{
byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
string imageBase = Convert.ToBase64String(bytes);
imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
<img id="#item.treasureID" src="#imageSource"/>
}
}
This code will show the user all the images they have chosen, however in if I take away window.location.reload(); this code is only updated when the page reloads. Meaning that the user will not see their chosen image immediately after they have chosen it.
What I want to do is update the code that calls the Learner_Table without refreshing the page.
There is another way to approach this problem, you could use the SignalR library.
This is what you would need to do:
View
// Include the SignalR Script
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
// Provide a dynamic proxy for SignalR
<script src="~/signalr/hubs"></script>
// Define hub connection(see below)
var hub = $.connection.yourHub;
// This is what the Hub will call (Clients.All.getImage(imageSource);)
hub.client.getImage = function (img) {
var image = '<img id="' + img.treasureId + '" src="data:image/jpg;base64,' + img.image + '"';
$(image).appendTo("body");
};
// Start the connection to the hub
// Once we have a connection then call the getLearnerTreasureItem on the Hub
$.connection.hub.start().done(function () {
var id = // whatever
hub.server.getLearnerTreasureItem(id);
};
Hub
public class YourHub : Hub
{
public void GetLearnerTreasureItem()
{
// All your code
List<The_Factory_Chante.Models.Learner_Treasure> lern;
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{
string imageSource = "";
lern = db2.Learner_Treasure.ToList();
if (lern != null)
{
foreach (var item in lern)
{
if (item.learnerID == UserInfo.ID)
{
byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
string imageBase = Convert.ToBase64String(bytes);
imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
}
}
// This will now call the getImage function on your view.
Clients.All.getImage(imageSource);
}
}
Information on the dynamic proxy
The way I approach this is by making a partial View for the code that needs to be refreshed
public PartialViewResult UserImages(your paramaters here)
{
your code here
}
And then after successful $.ajax I refresh it
var id = treshID
$.ajax({
url: "../../WebService.asmx/MakeSure",
data: "{ 'id': '" + id + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
$.ajax({
url: "/UserImages",
data: your data model here,
success(function(html)){
$("#yourPartialViewWrapperHere").html(html));
}
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
Your problem is the onclick event handler here:
<img id="#item.treasureID" src="#imageSource" onclick="return MakeSure(#item.treasureID)" />
In the MakeSure() function you don't return anything. So you have two options, change your MakeSure() function to return false at the end, or change the onclick event to return false after the first function call in the image element, like this onclick="MakeSure(#item.TreasureID); return false;"
Also you will have to remove the window.location.reload(); from the MakeSure() function.
Side note, it seems you are mixing up your DbContext in your view, if that's the case, this is very bad practice. You should put your data access behind some sort of service layer that serves as a mediator between the view and your data.
Update
Ok after reading your question a few times I understand your problem
The problem is your second piece of code.
List<The_Factory_Chante.Models.Learner_Treasure> lern;
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{
string imageSource = "";
lern = db2.Learner_Treasure.ToList();
if (lern != null)
{
foreach (var item in lern)
{
if (item.learnerID == UserInfo.ID)
{
byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
string imageBase = Convert.ToBase64String(bytes);
imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
<img id="#item.treasureID" src="#imageSource"/>
}
}
}
}
This calls the DB and gets a list of Learner_Treasure objects which you use to output on view. Server side code gets executed once every page request, this is exactly what is happening. It will not asynchronously update without a request to the server.
You need to implement an ajax request to pull the latest Learner_Treasure list into the view. Again this comes down to the first side note I gave, the reason is because you are mixing your dbcontext with your view and expecting it to update on the fly. If you implement a layer which serves your view with the data (controller), you could call this asynchronously and have the page update without it reloading.
For instance you could write a call in your controller to get a single LearnerTreasure item in json.
[HttpGet]
public ActionResult GetLearnerTreasureItem(int Id)
{
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext()) {
learnerTreasureItem = db2.Learner_Treasure.FirstOrDefault(x => x.Id == Id);
return Json(new { image = Convert.ToBase64String(learnerTreasureItem.itemImage), treasureId = learnerTreasureItem.TreasureID }, JsonRequestBehavior.AllowGet);
}
}
And then call it with ajax in your view, like you did with the update.
$.ajax({
cache: false,
type: "GET",
url: '/YOURCONTROLLERNAME/GetLearnerTreasureItem?id=1',
contentType: 'application/json',
dataType: "json",
success: function (data) {
//build image element
var image = '<img id="' + data.treasureId + '" src="data:image/jpg;base64,' + data.image + '"';
//add the image to where you need it.
$(image).appendTo("body");
},
error: function (xhr) {
alert("Error occurred while loading the image.");
}
});
I hope this helps.
Update in treasures images list
<img id="#item.treasureID" src="#imageSource" onclick="return MakeSure(this, #item.treasureID)" />
read that param in MakeSure method. also I just assume Learner_Treasure images listed in ul named 'ulLearnerTreasure'.
function MakeSure(sender,treshID) {
var id = treshID;
var imgSrc = $(sender).attr("src");
$.ajax({
url: "../../WebService.asmx/MakeSure",
data: "{ 'id': '" + id + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
var li = '<li><img id ="'+ treshID +'"src="'+ imgSrc +'" /></li>';
$("#ulLearnerTreasure").append(li);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
};
I would implement it using HtmlHelpers, like so: (as someone suggested, using db code directly is not a good practice, you need to change that.)
public static class HTMLHelpers
{
public static IHtmlString TreasureImages(this HtmlHelper helper, List<The_Factory_Chante.Models.Learner_Treasure> lern)
{
StringBuilder sb = new StringBuilder();
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{
string imageSource = "";
lern = db2.Learner_Treasure.ToList();
if (lern != null)
{
foreach (var item in lern)
{
if (item.learnerID == UserInfo.ID)
{
byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
string imageBase = Convert.ToBase64String(bytes);
imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
sb.Append("<li><img id='#item.treasureID' src='#imageSource'/></li>");
}
}
}
}
return new HtmlString(sb.ToString());
}
}
Placeholder for your images:
<ul id="TreaureImagesSection">
</ul>
In your cshtml page, load the list with this script, the first time or whenever you need the updated list
<script>
$.ajax({
cache: false,
type: "GET",
url: '/YOURCONTROLLER/TreasuresList',
contentType: 'application/json; charset=utf-8',
success: function (data) { // the data returned is List<The_Factory_Chante.Models.Learner_Treasure>
$("#TreaureImagesSection").html('#Html.TreasureImages(data)');
},
error: function (xhr) {
alert("Error occurred while loading the image.");
}
});
</script>
So having a bit trouble figuring out how to successfully use AJAX to call a method and retrieve data. I am being asked to do this, not exactly sure why but I would usually just handle all this stuff in a MVC environment in the Controller. But for now I am asked to do this in AJAX. I have a ASPX file that I am simply trying to see work so i can move on. So far none of the stack overflow suggestions helped.
Here's what I currently have:
.ASPX/source
<script type="text/javascript">
$(document).ready(function () {
$("#go").click(function () {
$.ajax({
type: "GET",
url: "Default.aspx/ItemData",
processData: true,
data: {},
dataType: "json",
success: function () { alert("yay") },
error: function () { alert("nay") }
});
});
});
</script>
And then in my Default.aspx.cs file I have a method 'ItemData'
[WebMethod]
public static NextCrew.Models.Item ItemData(string cookieID)
{
Item item = new Item();
item.name = "Fred";
item.idx = 1;
item.completed = 1;
return item;
}
(Item is simple a Model withg 3 properties: Name(string), idx(int) and completed(int) )
I am having a hard time figuring out what I am doing wrong here. Can someone please write an example of what I am trying to do? Just a simple GET request that I can return an object (once I get done testing I want to be able to connect to a DB so I need it to be an object) using AJAX.
I can't tell what I am doing wrong but I have some ideas:
1)maybe my url in the ajax isn't formatted properly?
2)do i need to pass anything into data if I have a parameter?
3)is my get method in the correct .cs file?
UPDATE
I was informed I need to have a special class to handle this. I tried to then make a .asmx and the AJAX is still not being called. Hoping someone sees an error that I missed.
<script>
$(function () {
$.ajax({
type: "POST",
contentType: "application/json",
url: "WebService2.asmx/GetItems",
data: "{}",
dataType: 'Json',
success: function (result) {
// alert(result.d);
$.each(result.d, function (index, ele) {
$("#Myddl").append("<option value='" + ele.value + "'>" + ele.text + "</option>");
})
}
});
})
</script>
.asmx
public class WebService2 : System.Web.Services.WebService
{
[WebMethod]
public List<Item2> GetItems()
{
//suppose data comes from database
var result = new List<Item2>() {
new Item2{ text="one",value="one"},
new Item2{ text="two",value="two"},
new Item2{ text="three",value="three"}
};
return result;
}
public class Item2
{
public string text { get; set; }
public string value { get; set; }
}
}
I have the following jQuery AJAX request:
function sendUpdate(urlToSend) {
var code = AccessCode;
var url = urlToSend;
var options = { error: function(msg) { alert(msg.d); },
type: "POST", url: "webmethods.aspx/UpdatePage",
data: "{ accessCode: " + code + ", newURL: '" + url + "' }",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function(response) { var results = response.d; } };
$.ajax(options);
}
And the corresponding ASP.NET WebMethod:
[WebMethod]
public static bool UpdatePage(string accessCode, string newURL)
{
bool result = true;
try
{
HttpContext.Current.Cache[accessCode + "l"] = newURL;
}
catch
{
result = false;
}
return result;
}
That all used to work correctly with "async:false", however I have to get rid of it as it freezes the browser until the response is received. Now the AJAX request above returns "undefined".
Could anybody tell me why it happens and where the problem is?
Thanks.
You should really make sure to properly encode this JSON. JSON.stringify is the most reliable method:
data: JSON.stringify({ accessCode: code, newURL: url })
This ensures that even if the code and url variables contain some dangerous characters that will break your string concatenations in the resulting JSON at the end everything will be properly encoded. The JSON.stringify method is natievly built into modern browsers but if you need to support legacy you could include json2.js.
Also because you code is no longer blocking you should make sure that if you call this sendUpdate from some button click or form submit you cancel the default action by returning false.
My way works correctly:
[System.Web.Services.WebMethod()]
public static string getHello(string str)
{
//do some things with str
return str;
}
In file .js, I define this function to call webmethod in file .cs:
function CallServerFunction(StrPriUrl, ObjPriData, CallBackFunction) {
$.ajax({
type: "post",
url: StrPriUrl,
contentType: "application/json; charset=utf-8",
data: ObjPriData,
dataType: "json",
success: function (result) {
if (CallBackFunction != null && typeof CallBackFunction != 'undefined') {
CallBackFunction(result);
}
},
error: function (result) {
alert('error occured');
alert(result.responseText);
window.location.href = "FrmError.aspx?Exception=" + result.responseText;
},
async: true
});
}
Then, call to use (call in file.js):
var text = $("#textbox_send").val();
var myresult;
CallServerFunction("Default.aspx/getHello", JSON.stringify({ str: text }), function (myresult) {
if (text != "")
$('#' + id).append('<p>' + $("#account_user").text() + ': ' + myresult.d + '</p>');
});
The "undefined" could be the result of a server error.If you use Firebug,Firefox(or any good client debugging tool), you can find the error returned by the server. Paste the error,if any.
Nevertheless, I also noted the the "data" for "accessCode" is not properly enclosed within quotes ‘ ’
The corrected data option would be :
data: "{ accessCode: '" + code + "', newURL: '" + url + "' }",
PS:
Since 'options' have a different meaning in Jquery, I would recommend changing the variable name as 'setting' . Change 'var options ' to 'var settings'. :)