我一直在尝试从我自己的JavaScript代码中调用Page Methods,但它不起作用。如果我使用jQuery AJAX,我可以成功调用Page Methods,但是我需要从我自己的JavaScript代码中执行此操作,因为我们不能使用第三方库(我们正在构建自己的库)。
每当我使用jQuery AJAX方法时,我都会得到Page方法的结果,当我使用自定义JS方法时,我会从AJAX请求中获得整页。
jQuery处理AJAX请求的方式必须有所不同。有谁知道它会是什么?
下面是我用jQuery调用同一个Page方法的代码,它运行起来,以及我用来自己调用它的代码。
的jQuery
// JScript File
$(document).ready(function() {
$("#search").click(function() {
$.ajax({
type: "POST",
url: "Account.aspx/GetData",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Substitui o conteúdo da DIV vom o retorno do Page Method.
displayResult(msg);
}
});
});
});
自定义JS
function getHTTPObject() {
var xhr = false;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
xhr = false;
}
}
}
return xhr;
}
function prepareLinks() {
var btn = document.getElementById("search");
btn.onclick = function() {
var url = "Account.aspx/GetData"
return !grabFile(url);
}
}
function grabFile(file) {
var request = getHTTPObject();
if (request) {
displayLoading(document.getElementById("result"));
request.onreadystatechange = function() {
parseResponse(request);
};
//Abre o SOCKET
request.open("GET", file, true);
//Envia a requisição
request.send(null);
return true;
} else {
return false;
}
}
function parseResponse(request) {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 304) {
var details = document.getElementById("result");
details.innerHTML = request.responseText;
fadeUp(details,255,255,153);
}
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(prepareLinks);
更新:我决定接受Stevemegson,因为他的回答是我问题的真正原因。但我想与你发现一些我发现这个问题的替代品。
Stevemegson的回答: 我所要做的就是更改为POST请求并将请求标头设置为JSON,这解决了我在请求页面方法时遇到的问题,但现在我在处理响应时遇到了困难(我会更多地说明这一点)在另一个问题上)。
以下是获取此内容的正确代码:
print("function prepareLinks() {
var list = document.getElementById("search");
list.onclick = function() {
var url = "PMS.aspx/GetData"
return !grabFile(url);
} }");
print("function grabFile(file) {
var request = getHTTPObject();
if (request) {
//Evento levantado pelo Servidor a cada mudança de Estado na
//requisição assíncrona
request.onreadystatechange = function() {
parseResponse(request);
};
//USE POST
request.open('POST', file, true);
//SET REQUEST TO JSON
request.setRequestHeader('Content-Type', 'application/json');
// SEND REQUISITION
request.send(null)
return true;
} else {
return false;
}
}");
Brendan的回答:通过Brendan的回答,我对ICallBack接口和ICallBackEventHandler进行了一些研究。令我惊讶的是,这是一种使用Microsoft的AJAX Request实现开发aspx页面的方法。事实证明这是一个非常有趣的解决方案,因为它不需要任何JS库来解决它在.Net Framework内部而且我相信只有少数人知道这些东西(至少那些在我周围的人没有'完全了解它。 如果您想了解更多信息,请在MS上查看link text,或者只复制并粘贴Brendan的答案。
第三个解决方案:我找到的另一个解决方案是,不是创建ASPX页面来处理我的服务器端代码,而是实现HTML页面并调用ASHX文件,这些文件会做同样的事情,但是他们会使用带宽比ASPX页面少。关于这个解决方案的一个很好的结果是我可以使用它来处理POST和GET请求。以下是代码。
ASHX代码:
print("Imports System.Web
Imports System.Web.Services
Public Class CustomHandler
Implements System.Web.IHttpHandler
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "text/plain"
Dim strBuilder As New System.Text.StringBuilder
strBuilder.Append("<p>")
strBuilder.Append("Your name is: ")
strBuilder.Append("<em>")
strBuilder.Append(context.Request.Form(0))
strBuilder.Append("</em>")
strBuilder.Append("</p>")
context.Response.Write(strBuilder.ToString)
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get End Property End Class");
JavaScript文件:
print("function prepareLinks() {
var list = document.getElementById("search");
list.onclick = function() {
var url = "CustomHandler.ashx"
return !grabFile(url);
}
}");
print("function grabFile(file) {
var request = getHTTPObject();
if (request) {
request.onreadystatechange = function() {
parseResponse(request);
};
//VERSÃO do POST
request.open('POST', file, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send('name=Helton Valentini')
return true;
} else {
return false;
} }");
使用这三个选项中的任何一个,我们可以在不使用JQuery的情况下进行异步调用,使用我们自己的Javacript或使用Microsoft在.Net Framework上嵌入的资源。
我希望这有助于我们中的一些人。
答案 0 :(得分:2)
一个相对简单的解决方案是让您的代码隐藏实现ICallbackEventHandler。 与jQuery相比,它有点粗糙,但它确实有用。
Partial Public Class state
Implements ICallbackEventHandler
Private _callbackArg As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
RegisterCallbackScript()
End Sub
Private Sub RegisterCallbackScript()
Dim cbRef As String = Page.ClientScript.GetCallbackEventReference(Me, "args", "RecieveServerData", "context")
Dim cbScript As String = "function CallServer(args, context) {" & cbRef & "; }"
ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", cbScript, True)
End Sub
Public Sub RaiseCallbackEvent(ByVal eventArgs As String) Implements ICallbackEventHandler.RaiseCallbackEvent
_callbackArg = eventArgs
End Sub
Private Function GetCallbackResults() As String Implements ICallbackEventHandler.GetCallbackResult
Dim args As String() = _callbackArg.Split(CChar("~"))
If args(0) = "search"
Return args(0) + "~" + GetSearchResults(args(1))
End If
End Function
Private Function GetSearchResults(ByVal keyword As String) As String
Dim htmlResults As String
//Build your html here
Return htmlResults
End Function
End Class
// JavaScript的
function searchButtonClicked(keyword) {
CallServer('search~' + keyword);
}
function RecieveServerData(arg, context) {
var args = arg.split('~');
switch(args[0]){
case 'search':
document.getElementById('result').innerHTML = args[1]
break;
}
}
希望这有帮助。
答案 1 :(得分:2)
您正在使用GET请求URL,而jQuery代码使用POST。我希望只能通过POST调用页面方法,以允许您在请求正文中包含任何参数。您可能还需要将请求的Content-Type设置为application / json,就像jQuery代码那样 - 我不知道.NET是否会接受其他内容类型。
答案 2 :(得分:1)
如果您使用的是ASP.NET AJAX,则无需执行任何操作。有一种定义明确的使用PageMethods的方法,它的复杂程度要低得多。
代码隐藏
[WebMethod]
public static Whatever GetWhatever( int someParameter, string somethingElse )
{
... make a Whatever ...
return whatever;
}
页
...
<script type="text/javascript">
function invokePageMethod(button)
{
var ctx = { control: button };
var someParameter = ...get value from a control...
var somethingElse = ...get another value from a control...
PageMethods.GetWhatever( someParameter, somethingElse, success, failure, ctx );
}
function success(result,context) {
... rearrange some stuff on the page...
}
function failure(error,context) {
... show some error message ...
}
</script>
...
<asp:ScriptManager runat="server" id="myScriptManager" EnablePageMethods="true">
</asp:ScriptManager>
...
<input type="button" onclick="invokePageMethod(this);" value="Do Something" />