2008-10-14 51 views
2

我一直试图从我自己的JavaScript代码中调用页面方法,但它不起作用。如果我使用jQuery AJAX,我可以成功调用页面方法,但是我需要从我自己的JavaScript代码中执行此操作,因为我们无法使用第三方库(我们正在构建自己的库)。如何在不使用jquery的情况下从javascript调用.net页面方法?

每当我使用jQuery AJAX方法时,我都会得到Page Method的结果,并且当我使用自定义JS方法时,我从AJAX请求中获取整个页面。

jQuery处理AJAX请求的方式必定有些不同。有谁知道它可能是什么?

下面是我用来调用相同的页面方法与jQuery,它的工作原理和我使用的代码,我自己调用它的代码。

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; 
} 
}"); 

布伦丹回答:通过布伦丹的回答我没有在ICallBack接口和ICallBackEventHandler一个小小的研究。令我惊讶的是,这是一种使用微软的AJAX请求实现来开发aspx页面的方法。这真的是一个非常有趣的解决方案,因为它不需要任何JS库来解决问题,而且它在.Net Framework内部,我相信只有少数人知道这个东西(至少那些在我身边的人并没有这样做)根本就不知道)。 如果你想知道更多关于ICallBack在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 embeeded上的资源.Net框架。

我希望这可以帮助我们中的一些人。

回答

2

您使用GET请求URL,而jQuery代码使用POST。我希望页面方法只能通过POST调用,以允许您在请求的主体中包含任何参数。您可能还需要将请求的Content-Type设置为application/json,就像jQuery代码一样 - 我不知道.NET是否会接受其他内容类型。

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

如果您使用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" /> 
+0

为了做到这一点我必须把脚本管理我的网页上,并设置启用页面方法为True,这样的代理会创建。使用我上面描述的例子,我不需要做任何这些。 – user27813 2008-10-15 16:22:01

相关问题