如何在没有jquery的情况下从javascript调用.net页面方法?

时间:2008-10-14 12:02:57

标签: jquery .net ajax

我一直在尝试从我自己的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上嵌入的资源。

我希望这有助于我们中的一些人。

3 个答案:

答案 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" />
相关问题