现在的位置: 首页 > 综合 > 正文

Using ASP.Net AJAX WebServices (ScriptServices) in ExtJS

2013年12月09日 ⁄ 综合 ⁄ 共 5193字 ⁄ 字号 评论关闭
 I've only just started investigating ExtJS and what it can possibly provide over and above the ASP.Net AJAX framework. The first thing I wanted to do was use the ASP.Net AJAX JavaScript webservice proxies instead of the expected REST style services. Unfortunately I ran into several problems and ended up using a slightly different approach to what I found on the ExtJS forums. Let me quickly outline the problem. In ExtJS they use a store wrapper for their data which is assigned to a grid panel. This store object may also know how to fetch external data that it needs via a proxy, which is defined like so:

var ds = new Ext.data.Store({
    proxy: 
new Ext.data.HttpProxy(
         {
          url: 
'/WebServices/OrderService.asmx/GetOrders',
          params: { userId: getUserId(), day: 
new Date() }
         }),
    reader: 
new Ext.data.JsonReader(
        {
           id: 
'WorkDoneId'
        
},
    ...
})
;


Unfortunately, try as I might to get this to call my web service (and I tried quite a few different approaches), I would get errors returned by the service. It may have been that unlike all the examples I had seen on the web, like Daniel Larson's my service calls actually needed to send parameters through to the service. One was to add additional properties to the ScriptMethod attribute on the web service like so:

[ScriptMethod(ResponseFormat ResponseFormat.Json, UseHttpGet = true, XmlSerializeString = false)]


I also tried using the ASPProxy class found on this forum post. This also didn't work properly and there were a few minor irritations with the code. It all seemed pretty silly since with the ScriptManager service reference I had a client side proxy that I knew would work properly. So I created the AspWebServiceProxy object that would allow you to simply pass in a reference to the client side web service proxy object and method and use that:

AspWebServiceProxy = function (conn)
           {
              AspWebServiceProxy.superclass.constructor.call(
this);
              
Ext.apply(this, conn);
           
};

Ext.extend(AspWebServiceProxy, Ext.data.DataProxy, 
{
     load : 
function (params, reader, callback, scope, arg)
            {
               
var userContext {
                                    callback: callback, 
                                    reader: reader, 
                                    arg: arg, 
                                    scope: scope
                                 }
;
               
               var 
proxyWrapper = this;
               
               
//Handles the response we get back from the web service call
               
var webServiceCallback = function(response) 
                                        { 
                                            proxyWrapper.loadResponse(response, userContext)

                                        
}
               
               
var serviceParams [];
               
               
//Convert the params into an array of values so that they can be used in the call (note assumes that the properties on the object are in the correct order)
               
for (var property in params)
               {
                  serviceParams.push(
params[property]);
               
}
               
               
//Add the webservice callback handlers
               
serviceParams.push(webServiceCallback);
               
serviceParams.push(this.handleErrorResponse);
               
               
//Make the actual ASP.Net web service call
               
this.webServiceProxyMethod.apply(this.webServiceProxy, serviceParams)
            
},
            
     handleErrorResponse : 
function(response, userContext, methodName)
                           {
                              
alert("Error while calling web service method:" + methodName + "/n" + response.get_message());
                           
},
 
     loadResponse : 
function (response, userContext, methodName)
                    {
                        
var result userContext.reader.readRecords(response);
                        
userContext.callback.call(userContext.scope, result, userContext.arg, true);
                    
}
        
})
;


So if you had an ASP.Net web service script reference on your page, like this:

<asp:ScriptManager ID="PageScriptManager" runat="server">
    
<Services>
        
<asp:ServiceReference Path="/WebServices/OrderService.asmx" InlineScript="false" />
    </
Services>
</asp:ScriptManager>


to use the proxy class one would change the code at the start of the article to look like this:

 var ds = new Ext.data.Store({
    proxy: 
new AspWebServiceProxy(
         {
          webServiceProxy: Example.OrderService,
          webServiceProxyMethod: Example.OrderService.GetOrders,
          params: {userId: getUserId(), day: 
new Date()}
         }),
    reader: 
new Ext.data.JsonReader(
        {
           id: 
'WorkDoneId'
        
},
    ...
})


I'm sure that I'll be tweaking the AspWebServiceProxy object over time as I discover its short comings, but at least it is a decent start and is hopefully useful to others as well. One of my concerns are the manner in which the attributes on the extraParams object must be specified in the same order as the web service method parameters. I did it this way to keep it consistent with all the other examples I had seen where they used an object as opposed to an array. I may change this, but I like the fact that with the current approach the parameter value pairs are obvious.

Update - 2 Nov 2007: Changed the service options of extraParams to params. So now one can use dataStore.load({params: {userId: 4, day: new Date()} }) to load data after the creation of the data source. 

http://www.ridgway.co.za/demos/ExtJSScriptServiceExample.zip

抱歉!评论已关闭.