我的.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);
}
现在我想通过javascript方法将此方法称为页面方法,但它不起作用。
<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>
我的.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
}
我的界面:
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; }
}
答案 0 :(得分:6)
首先,谢谢你澄清你的问题。有点难以理解你试图解决的问题。原因?因为您的代码不够清晰,并且通常在存在设计问题时发生。这实际上是你面临的一个设计问题。首先,我会指出一些错误......
在这个javascript函数中......
function GetInfo() {
PageMethods.GetServiceInformation(this);
}
this
不是您网页的实例。所以没有必要让你的页面实现一个接口...
public partial class AppMaster : Log, IInfo{}
并期望javascript调用会将System.Web.UI.Page
的实例分页到您的类(更不用说IInfo
接口的实现)。你可以盲目地抛弃这种方法,因为这是一个永久性的设计问题,甚至都无法发挥作用。
现在,如果你想要的是服务页面,那么做一些进一步的处理,最后使用javascript / ajax异步地将这个处理的结果发送回客户端你有几种方法:
SignalR
这是我最喜欢的方法(但您已说明您的解决方案不符合使用SignalR
的要求)jQuery
ajax,这也是一种非常有效的方法现在,我将解释第二种方法
jQuery
Ajax 只需像在ASP.NET
中一样呈现页面。然后在客户端,当页面加载时,发出ajax请求以开始处理您要显示的信息。您可以在页面加载后立即启动请求以在服务器上进行处理
$(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
}
});
});
在成功处理程序中,您需要在Web控件上加载从ajax调用接收的值。然后将IInfo
接口更改为单独代码文件中的具体对象。但是,请记住,此类不应该对您的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; }
}
然后将您的页面方法更改为...
[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;
}
请注意,您需要从emp_num
获取Session
值,因为您在聊天讨论中声明此值来自Session
变量。现在,返回到jQuery
ajax调用的成功处理程序,该调用在从服务器收到响应后立即执行。您将在处理程序参数d
中收到一个json对象,其中包含您刚刚从服务器发送的JSInfo
类的属性。然后在页面上设置控件......
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
},
这应该是一个更简洁的解决方案。在这里,我无法涵盖每一个细节。但肯定你会明白这个想法。如果没有,请告诉我是否需要扩展某些内容。
答案 1 :(得分:5)
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);
}
}
抱歉,如果它不起作用
答案 2 :(得分:3)
如果您的页面实现了界面,则不必传递它!在你的c#代码中写:
this.l_power=true;
如果需要将值从JavaScript传递给页面方法,请将每个属性定义为参数并将值传递给页面方法:
[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";
}
和
<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>
其中success
和fail
是在请求完成后将调用的两个JS函数的名称。请注意,页面方法可以返回字符串值,以通知客户端服务器上发生了什么。
答案 3 :(得分:2)
我只能想到一种方法。
您应该以某种方式封送this
对象,并将其作为参数发送。我的意思是你应该编写一个方法,将一个对象编组为等效的json或xml,并将POST
编组到你的服务器上。
我相信你可以像上面那样只通过C#
和javascript之间的干净API和编译工具来实现RPC
,就像为GWT
编写java
一样和javascript。
答案 4 :(得分:2)
你能做一点测试吗?
在您的页面代码中声明public class JSInfo: IInfo{}
,并在您的Web方法中将您的参数声明为JSInfo。
当JSInfo实现IInfo时,您的程序逻辑可以毫无问题地使用它。
只是为了让您知道,您的代码无法正常工作,因为您无法将接口序列化 不是具体的类型,如果你考虑一下,接口在XML模式中没有真正的相关性。没有办法表示数据。然而,基类将起作用。
如果你在asp.net页面类中声明JSInfo时填写不好,那么创建一个名为的类 WebMethodsHelper并在那里声明您的JavaScript WebMethod接口(适配器)。
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);
}
}
JSInfo只是给你的IInfo接口一些结构,因此可以序列化。
从JavaScript中你应该能够像这样称呼你的页面方法:
<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>
不是说你的页面顶部应该有一个ScriptManager
<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server" />
ScriptManager负责为您提供JavaScript中的PageMethods类 与其他事情。
另外,请确认以下内容:
答案 5 :(得分:2)
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);
}
}
然后
<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);
提到@anotherdie。并告诉你如何转移“X”
答案 6 :(得分:2)
在你的.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);
});
}
在你的apsx.cs中(你可以返回一个字符串,一个列表,一个bool,一个int或一个json对象//为json使用json.net http://james.newtonking.com/json)为此我将返回一个bool。
using System.Web.Services;
[WebMethod]
public static bool GetServiceInformation(ClassData parameters)
{
try
{
//do some
return true;
}
catch(Exception ex)
{
return false;
}
}
在接口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;
}
答案 7 :(得分:0)
我执行以下操作:
创建新页面并调用它: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 + "~";
}
并在我的主页中:
<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>