2008-10-14 49 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

相關問題