I have a WebMethod in the code behind which is not being hit. I've googled a lot and found lots of questions like this. I've tried all suggestions I've seen whit no success.
IDE: Visual Studio 2017
Framework: 4.0
jQuery version: 3.1.1
Project type: Webforms (yeah, I miss my beloved MVC but it's not my fault!)
The error:
{"Message":"Invalid web service call, missing value for parameter:
\u0027id\u0027.","StackTrace":" at
System.Web.Script.Services.WebServiceMethodData.CallMethod(Object
target, IDictionary2 parameters)\r\n at
System.Web.Script.Services.WebServiceMethodData.CallMethodFromRawParams(Object
target, IDictionary2 parameters)\r\n at
System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext
context, WebServiceMethodData methodData, IDictionary`2 rawParams)\r\n
at
System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext
context, WebServiceMethodData
methodData)","ExceptionType":"System.InvalidOperationException"}
URL being called: GET http://localhost:65050/Default.aspx/Save?{"id":"chkEditable","wasChecked":"on"}
When I click on any of the two check boxes, I get the following error on Chrome console
GET
http://localhost:65050/Default.aspx/Save?{%22id%22:%22chkEditable%22,%22wasChecked%22:%22on%22}
500 (Internal Server Error) jquery-3.1.1.min.js:4
Here's my aspx code:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="TesteWebMethod.Default" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-3.1.1.js"></script>
<script src="Scripts/jquery-3.1.1.min.js"></script>
<script>
$(document).ready(function () {
$('#chkVisible').change(function () {
Save('chkVisible', $('#chkVisible').val());
});
$('#chkEditable').change(function () {
Save('chkEditable', $('#chkEditable').val());
});
});
function Save(_id, _state) {
var pageUrl = '<%= ResolveUrl("~/Default.aspx")%>';
var _data = { "id": _id, "wasChecked": _state };
$.ajax({
type: "GET",
url: pageUrl + "/Save",
data: JSON.stringify(_data),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: OnFailure
});
}
function OnFailure(response) {
console.log('falha');
alert(response.d);
}
function OnSuccess(response) {
console.log('sucesso');
alert(response.d);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:CheckBox runat="server" AutoPostBack="false" ID="chkVisible" Text="Visivel" />
<asp:CheckBox runat="server" AutoPostBack="false" ID="chkEditable" Text="Editavel" />
</form>
And here is the code-behind
using System;
using System.Web.Script.Serialization;
using System.Web.Script.Services;
using System.Web.Services;
namespace TesteWebMethod
{
public partial class Default : System.Web.UI.Page
{
[WebMethod(true)]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public static string Save(string id, string wasChecked)
{
bool b = wasChecked == "on";
string data = "Id " + (b ? "was checked" : "was unchecked");
JavaScriptSerializer TheSerializer = new JavaScriptSerializer();
var json = TheSerializer.Serialize(data);
return json;
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
I really got stuck on this. Can someone tell me what I'm doing wrong?
My answer would be that the method you are calling is a GET method, but you are passing data as if the method were a POST method. Webforms will not take parameters out of the request content and act like they came from the query string. That JSON data you are including in the request needs to be URL encoded into the query string, or the method needs to be converted into a POST method as well as the AJAX call.
You shouldn't stringify your json object if you set your object to the data property jquery will know how to build a GET request.
$.ajax({
type: "GET",
url: pageUrl + "/Save",
data: {"id": _data.id, "wasChecked": "'" + _data.wasChecked + "'"},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: OnFailure
});
Notice that I had to curate the data adding single quotes to the wasChecked attribute because That's the way ASP knows that's a string, which I think it's a terrible implementation.
As Kevin said, a POST would be much better. It would
$.ajax({
type: "POST",
url: "WebMethodTest.aspx/Save",
data: JSON.stringify({ "id": 2, "wasChecked": "test" }),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
And
[WebMethod(true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string Save(string id, string wasChecked)
{
Related
I'm changing Jquery version from jquery-1.10.2 to jquery-3.6.3 but the method callings are not working due to this version change. My .NET Framework version is 4.7.2
I have used the new reference like below:
<script src="../Scripts/Version3.6.3/jquery-3.6.3.min.js?version=<%=ApplicationVersion.GetApplicationVersion()%>" type="text/javascript"></script>
calling client side JQuery POST method:
$.post("/employer/employerbrowse.aspx/SelectEmployer",
{ key: key },
function (data, textStatus, jqXHR) {
alert(data);
});
c# method:
[WebMethod(EnableSession = true)]
[ScriptMethod(UseHttpGet = false)]
public string SelectEmployer(string key)
{
string strUrl = "";
return strUrl;
}
After calling the "SelectEmployer" method it redirecting to page load only not in the desired page method.
Thanks in advance.
use AJAX to make the call to webMethod
$.ajax(
{
type: "POST",
url: "employerbrowse.asmx/SelectEmployer",
data: JSON.stringify({ key: _key}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(data);
}
}
);
Further ... I notice your webmethod is in a normal aspx page, whenever ive tried that it hasnt worked and needed to add a Web Service (asmx) but you might be alright... Youd keep js/ajax call in aspx page if using this.
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.
I want to display data in a table based on the search criteria in a textbox. I have implemented it without using Ajax but do not know how to call controller method using jquery and update table data. Please try to solve my problem. Thanks...
Index.cshtml
#model IEnumerable<MvcApplication4.Models.tbl_product>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<script src="#Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<title>Index</title>
<script type="text/javascript">
$(document).ready(function () {
$('#Button1').click(function () {
alert("button clicked");
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'Home/Index',
data: "{'searchString':'" + document.getElementById('searchString').value + "'}",
async: false,
Success: function (response) {
alert("Success");
window.location.reload();
},
error: function () { alert("error"); }
});
});
});
</script>
</head>
<body>
#* #using (#Html.BeginForm("Index", "Home"))
{*#
#Html.TextBox("searchString");
<input type="button" value="filter" id="Button1" />
#* }*#
<table id="showData">
#{Html.RenderPartial("SearchList");}
</table>
</body>
</html>
SearchList.cshtml(Partial View)
#foreach (var item in Model)
{
<tr>
<td>#item.ProductName</td>
<td>#item.ProductId</td>
<td>#item.ProductDesc</td>
</tr>
}
HomeController.cs
public class HomeController : Controller
{
//
// GET: /Home/
ProductEntities dbentity = new ProductEntities();
public ActionResult Index()
{
return View(dbentity.tbl_product.ToList());
}
[HttpPost]
public ActionResult Index(string searchString)
{
var query = dbentity.tbl_product.Where(c => c.ProductName.Contains(searchString));
return View(query.ToList());
}
}
$.ajax({
url: '/ControllerName/ActionName',
type: "POST",
data: {criteria: 'criteria'},
contentType: "application/json",
success: function (data) {
//Replace existing table with the new view (with the table).
}
});
//write ControllerName without the key controller.
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'Home/Index',
data: JSON.stringify({'searchString':document.getElementById('searchString').value }),
async: false,
Success: function (response) {
alert("Success");
//append the data in between table tbody like,
$('table tbody').html(response);
//No window.location.reload(); It will cause page reload initial data will appear in grid.
},
error: function () { alert("error"); }
});
return false
Hope this helps.
Your ajax request should look like:
$.ajax({
url: '/<ControllerName>/<MethodName>',
type: "POST",
data: requestData,
contentType: "application/json;charset=utf-8",
success: function (data, textStatus, XMLHTTPRequest) {
//Success callback handling
},
error: function (XMLHTTPRequest, textStatus, errorThrown) {
//Error callback handling
},
cache: false //whether you want to cache the response or not.
});
I'm not going to give you the exact answer, but to help you to get it.
There are two steps:
First you must get sure the request is being done, and the response is being get on the browser.
To do so, you can
do it on your way: leave only the alert("Success"); and check it's being run.
better than that, open the browser's developer console (I prefer Chrome, but you can also use IE or FireFox + FireBug add-on) using F12. Set breakpoints and inspect variable values and code flow. See thit tutorial for Chrome developer tools.
set a breakpoint on the server action, and check it's executed
Second Once you're sure the firs part is working fine, use your succes function to replace the table content with the data received in the response. You can do it in several ways with jQuery. For example
$('#showData').html(response);
Again, you can execute this code and inspect the contents of response from the developer's console in your browser. This makes things eaiser when you're starting to use javascript.
(If your action generated the whole table, you could use jQuery's replaceWith which replaces the target, instead of its content. Don't use this for this case).
FINAL NOTE: please, remove this code window.location.reload();!!! This reloads the whole page with the current URL, so whatever thing you do in advance will be lost.
I'm using the JQuery autocomplete plug in, and am passing in an array of strings to autocomplete (see code below). The method I'm calling to get my data (GetCustomerNames) is just returning an array of strings, and that is working fine. I need to find some way to pass in a parameter to the GetCustomerNames Method so I can filter what is being returned. Can anyone help with this?
Here is the markup code in the Default.aspx page:
<head runat="server">
<title></title>
<script type="text/javascript" src="js/jquery-1.3.2.js" ></script>
<script type="text/javascript" src="js/jquery.autocomplete.js" ></script>
<script type="text/javascript">
//Working, but uses results output to an aspx page using StringBuilder, trying
//to find a way to get the data with json
//$(document).ready(function() {
// $("#example").autocomplete('AutoCompleteData.aspx');
//});
$(document).ready(function() {
$("#example").keyup(function() {
$.ajax({
type: "POST",
url: "Default.aspx/GetCustomerNames",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
$("#example").autocomplete(msg.d);
},
error: function(msg) {
alert("error");
}
});
});
});
</script>
Customer Name:
And here is the code in the Default.aspx.cs code behind page implementing the GetCustomerNames method:
[WebMethod]
public static string[] GetCustomerNames()
{
string[] data = new string[] {"Andrew", "Ramona", "Russ", "Russell", "Raymond"};
return data;
}
You could use the data hash to pass parameters to the method:
$.ajax({
type: 'POST',
url: 'Default.aspx/GetCustomerNames',
data: '{ parameterName: "some test value" }',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(msg) {
$("#example").autocomplete(msg.d);
},
error: function(msg) {
alert("error");
}
});
And your web method becomes:
public static string[] GetCustomerNames(string parameterName)
I have a really simple AJAX method inside my Default.aspx.cs and it looks like this:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static string GetDate()
{
return DateTime.Now.ToString();
}
}
And the Default.aspx looks like this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" src="http://192.168.1.2/tizma.com/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Add the page method call as an onclick handler for the div.
$("#Result").click(function() {
$.ajax({
type: "POST",
url: "Default.aspx/GetDate",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: AjaxSucceeded,
error: AjaxFailed
});
});
});
function AjaxSucceeded(result)
{
alert(result.d);
}
function AjaxFailed(result)
{
alert(result.status + " " + result.statusText);
}
</script>
</head>
<body>
<div id="Result">Click me</div>
</body>
</html>
The problem is when I click the div the ajax error function is all that is ever called with a 200 status.
What am I doing wrong?
Not sure if it's causing the problem but you have a line which reads:
data: "{}",
it should read:
data: {},
or you can omit the line altogether as it's an optional parameter to the method call. You are currently setting it to a string value when it actually expects parameters for the webmethod which might cause problems.
Also, the lines reading:
contentType: "application/json; charset=utf-8",
dataType: "json",
seem unnecessary to me because for starters, it isn't obvious that your webmethod is actually returning json. I think it's just returning a string. Try removing those three lines alltogether and see if it doesn't just start working.