event javascript jquery asp.net ajax pagemethods

javascript mouse click event



¿Cómo llamar al método de página con un parámetro a través de un evento javascript? (8)

Tengo método como este en mi .cs:

[System.Web.Services.WebMethod] public static void GetServiceInformation(IInfo x) //IInfo is an interface { x.l_power = true; x.lb_InboxCount = UserTrans.GetInbox(int.Parse(emp_num), 0); }

Ahora quiero llamar a este método a través de un método javascript como método de página, pero no funciona.

<script type ="text/javascript"> function GetInfo() { PageMethods.GetServiceInformation(this); } window.onload = setTimeout("GetInfo()", 3000); </script>

<telerik:RadScriptManager ID="RadScriptManager1" runat="server" EnablePageMethods="true"> </telerik:RadScriptManager>

Mis .cs:

public partial class AppMaster : Log, IInfo //My page { public string Inbox { get { return hpl_Inbox.NavigateUrl; } set { hpl_Inbox.NavigateUrl = value; } } public string Draft { get { return hpl_Draft.NavigateUrl; } set { hpl_Draft.NavigateUrl = value; } } public string New { get { return hpl_New.NavigateUrl; } set { hpl_New.NavigateUrl = value; } } public string Approved { get { return hpl_Approved.NavigateUrl; } set { hpl_Approved.NavigateUrl = value; } } //------- etc }

Mi interfaz:

public interface IInfo { string Inbox { get; set; } string Draft { get; set; } string New { get; set; } string Approved { get; set; } string archive { get; set; } string search { get; set; } string cand { get; set; } string pri { get; set; } string power { get; set; } string admin { get; set; } string help { get; set; } bool l_cand { get; set; } bool l_pri { get; set; } bool l_power { get; set; } bool l_admin { get; set; } string lb_ApprovedCount { get; set; } string lb_InboxCount { get; set; } string lb_archive { get; set; } string lb_DraftCount { get; set; } }


Respuesta Editar basado en discusión de chat

Primero, gracias por aclarar tu pregunta. Fue un poco difícil entender el problema que intentabas resolver. ¿La razón? Debido a que su código no fue lo suficientemente claro y eso suele ocurrir cuando hay problemas de diseño. Eso es efectivamente lo que estás enfrentando aquí un poco de un problema de diseño. Primero, voy a señalar algunos errores ...

En esta función javascript ...

function GetInfo() { PageMethods.GetServiceInformation(this); }

this NO es una instancia de tu página. Así que no sirve de nada hacer que tu página implemente una interfaz ...

public partial class AppMaster : Log, IInfo{}

y espere que una llamada javascript IInfo una instancia de System.Web.UI.Page a su clase (sin mencionar una implementación de la interfaz IInfo ). Puede abandonar este enfoque a ciegas porque es un problema de diseño permanente y ni siquiera va a funcionar.

Ahora, si lo que desea es servir la página, realice un procesamiento adicional y finalmente envíe los resultados de este procesamiento al cliente de forma asíncrona utilizando javascript / ajax. Aquí tiene un par de enfoques:

  1. Uso de SignalR que es mi método favorito (pero usted ya indicó que su solución no cumple con los requisitos para usar SignalR )
  2. Usar jQuery ajax, que también es un enfoque muy válido.

Ahora, voy a explicar el segundo enfoque.

Usando jQuery Ajax

Simplemente renderice la página como lo haría normalmente en ASP.NET . Luego, en el lado del cliente, cuando se carga la página, realice una solicitud ajax para comenzar a procesar la información que desea mostrar. Puede iniciar la solicitud en cuanto se cargue la página para realizar el procesamiento en el servidor.

$(function(){ $.ajax({ type: ''POST'', url: ''AppMaster.aspx/GetServiceInformation'', data: "{}", contentType: ''application/json;charset=utf-8'', dataType: ''json'', success: function(d) { //load data received }, error: function() { //process the error } }); });

En el controlador de éxito, debe cargar los valores recibidos de la llamada ajax en sus controles web. Luego, cambie su interfaz IInfo a un objeto concreto en un archivo de código separado. Pero, recuerde que esta clase NO debe contener ninguna referencia a sus controles web

public class JSInfo { string Inbox { get; set; } string Draft { get; set; } string New { get; set; } string Approved { get; set; } string archive { get; set; } string search { get; set; } string cand { get; set; } string pri { get; set; } string power { get; set; } string admin { get; set; } string help { get; set; } bool l_cand { get; set; } bool l_pri { get; set; } bool l_power { get; set; } bool l_admin { get; set; } string lb_ApprovedCount { get; set; } string lb_InboxCount { get; set; } string lb_archive { get; set; } string lb_DraftCount { get; set; } }

luego cambia el método de tu página a ...

[System.Web.Services.WebMethod] public static JSInfo GetServiceInformation() { //you need to get the emp_num from session //construct the JSInfo object JSInfo info = new JSInfo(); //get the data from the database var data = UserTrans.GetInbox(int.Parse(emp_num), 0); //set the properties of the JSInfo...similar to the line below for each property...Draft, New, Approved, etc info.Inbox = data.Inbox; //return the object to the client return info; }

Tenga en cuenta que debe obtener el valor de emp_num de Session ya que en la conversación de chat indicó que este valor proviene de una variable de Session . Ahora, volviendo al controlador de éxito de su llamada jQuery ajax, que se ejecuta poco después de que se recibe la respuesta del servidor. Recibirá un objeto json en el parámetro del controlador d con las propiedades de la clase JSInfo que acaba de enviar desde el servidor. A continuación, establece los controles en la página ...

success: function(d) { $(''#id_inbox_control'').val(d.Inbox); $(''#id_draft_control'').val(d.Draft); $(''#id_new_control'').val(d.New); //and keep doing the same for the rest of the controls },

Eso debería ser una solución más limpia. Por supuesto, no puedo cubrir todos los detalles aquí. Pero seguro que obtendrás la idea. Si no, déjame saber si necesito ampliar algo.


¿Puedes hacer una pequeña prueba?

Declare una public class JSInfo: IInfo{} en el código de su página y en su método web declare ese parámetro suyo como JSInfo.

A medida que JSInfo implementa IInfo, la lógica de su programa puede funcionar con él sin ningún problema.

Solo para informarle, su código no funciona porque no puede serializar interfaces, ya que no son tipos concretos. Si lo piensa, las interfaces no tienen una correlación real en el esquema XML. No hay manera de representar los datos. Las clases de base funcionarán sin embargo.

Si no cumple con los requisitos para declarar el JSInfo en la clase de la página asp.net, cree una clase llamada WebMethodsHelper y declare allí sus interfaces de WebMethod (adaptadores) de JavaScript.

public class JSInfo: IInfo{ private ControlsCollection controls; public JSInfo(ControlsCollection constrols){ this.controls = controls FillObjects(); } private void FillObjects(){ //iterate through controls and extract you data to you //class properties/fields } public void Update(ControlsCollection controls){ this.controls=controls; FillObjects(); } public void Update(JSInfo info, ControlsCollection controls){ this.controls=controls; //populate your object based on info //then extract data from page controls FillObjects(); } } public class MyPage: System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e){ if(!IsPostBack && Session["info_obj"]) Session["info_obj"] = new JSInfo(this.Controls); } [System.Web.Services.WebMethod] public static string GetServiceInformation(JSInfo data) { JSInfo info = new JSInfo(this.Controls); info.Update(data); //or if you stored the info in the session JSInfo info = (JSInfo)Session["info_obj"]; info.Update(this.Controls, data); } }

El JSInfo es solo para darle a su interfaz IInfo cierta estructura para que pueda ser serializada.

Desde JavaScript deberías poder llamarte método de página como este:

<script type ="text/javascript"> function GetInfo() { var info = new JSInfo(); info.PropertyXPTO="something"; PageMethods.GetServiceInformation(info, onSuccess, onError); } function onSuccess(result) { alert(result); } function onError(result) { alert(''error: '' + result); } window.addEventListener("load", function(){ setTimeout("GetInfo()", 10 * 1000); }, false); </script>

No es que debas tener un ScriptManager en la parte superior de tu página

<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server" />

El ScriptManager es responsable de proporcionarle la clase PageMethods en el JavaScript, junto con otras cosas.

Además, confirme lo siguiente:

  • El método de la página debe tener el atributo System.Web.Services.WebMethod. [Método Web]
  • El método de la página debe ser público. [Método Web] público ...
  • El método de la página debe ser estático. [WebMethod] public static ...
  • El método de la página se debe definir en la página (ya sea en línea o en el código subyacente). No se puede definir en un control, página maestra o página base.
  • ASP.NET AJAX Script Manager debe tener EnablePageMethods establecido en verdadero.

En tu .js

function GetInfo() { var parameter = {}; parameter.name = "test"; parameter.id = 123; parameter.state = true; PageMethods.GetServiceInformation(parameter, function (res) { if (res == true) { //do some alert("ok"); } else { //do some alert("bad"); } }, function(err){ alert("ERROR: "+err._message); }); }

en su apsx.cs (puede devolver una cadena, una lista, un bool, un int o un objeto json // para json use json.net http://james.newtonking.com/json ) para esto, devolveré un bool

using System.Web.Services; [WebMethod] public static bool GetServiceInformation(ClassData parameters) { try { //do some return true; } catch(Exception ex) { return false; } }

en una interfaz ClassData .cs

public string name { get; set; } public int id { get; set; } public bool state { get; set; } public ClassData(){} public ClassData(string _name, int _id, bool _state) { this.name = _name; this.id= _id; this.state = _state; }


Sólo puedo pensar en un método.

De alguna manera, debe ordenar el objeto y enviarlo como parámetro. Quiero decir que debe escribir un método que haga corresponder un objeto a un json o xml equivalente, y POST eso a su servidor.

Creo que puedes hacerlo como lo hiciste anteriormente solo a través de una API limpia y una herramienta de compilación entre C# y javascript para implementar RPC al igual que GWT se escribió para java y javascript.


Si su página implementa la interfaz, ¡no tiene que pasarla! En su código c # escriba:

this.l_power=true;

Si necesita pasar valores de JavaScript al método de la página, defina cada propiedad como un parámetro y pase los valores al método de la página:

[System.Web.Services.WebMethod] public static string GetServiceInformation(int value1, string value2) { l_power = value1; something = value2; return "some string to indicate the result of call"; }

Y:

<script type ="text/javascript"> var v1 = 15; var v2 = "some value"; function GetInfo() { PageMethods.GetServiceInformation(v1, v2, success, fail); } window.onload = setTimeout("GetInfo()", 3000); </script>

donde success y fail son los nombres de dos funciones JS que se llamarán después de que se complete la solicitud. Tenga en cuenta que un método de página puede devolver un valor de cadena para informar al cliente sobre lo que sucedió en el servidor.


Yo hago lo siguiente:

Crea una nueva página y la llama: Counts.aspx

protected void Page_Load(object sender, EventArgs e) { emp_num = int.Parse(Session["empnum"].ToString()); Thread.Sleep(3000); string res = GetCounts(emp_num); Response.Write(res); } /***********************************************************************************************/ protected string GetCounts(int empNum) { string outbox = UserTransaction.getoutboxCount(empNum, 0); string inbox = UserTransaction.getinboxCount(empNum, 0); string archive = UserTransaction.getarchivecount(empNum, 0); string draft = UserTransaction.getdraftcount(empNum, 0); return outbox + "~" + inbox + "~" + archive + "~" + draft + "~"; }

y en mi pagina principal:

<script type="text/javascript"> function loadXMLDoc() { var xmlhttp; if (window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { var split = xmlhttp.responseText.split(''~''); var outbox = split[0]; var inbox = split[1]; var archive = split[2]; var draft = split[3]; document.getElementById("lbl_DraftCount").innerHTML = draft; document.getElementById("lbl_InboxCount").innerHTML = inbox; document.getElementById("lbl_ApprovedCount").innerHTML = outbox; document.getElementById("lbl_archive").innerHTML = archive; } } xmlhttp.open("GET", "Counts.aspx", true); xmlhttp.send(); } loadXMLDoc(); </script>


function GetServiceInformation(x) { $.ajax({ type: "POST", url: "page.aspx/GetServiceInformation", data: "{''x'':''" + x + "''}", contentType: "application/json; charset=utf-8", dataType: "json", success: on_sucess, error: on_error }); function on_sucess(data, status) { alert(data); } function on_error(request, status, error) { alert(error); } }

Lo siento, si no funciona.


function GetServiceInformation(x) { $.ajax({ type: "POST", url: "page.aspx/GetServiceInformation", data: x, //Attention: there is no {} contentType: "application/json; charset=utf-8", dataType: "json", success: on_sucess, error: on_error }); function on_sucess(data, status) { alert(data); } function on_error(request, status, error) { alert(error); } }

Y entonces

<script type ="text/javascript"> function GetInfo() { var myInfo = { Inbox: "", Draft: "", New: "", l_cand: "" ......//Attention, you should make this class corresponding to your server class IInfo }; PageMethods.GetServiceInformation(myInfo); } window.onload = setTimeout("GetInfo()", 3000);

Referido a @anotherdie. Y te diré cómo transferir "X".