如何在AJAX应用中访问ADO.NET Data Service
下面这个例子演示了如何使用ASP.NET AJAX的技术访问到ADO.NET Data Service,并且实现了数据的增删改查等常规操作
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="jquery-1.3.2-vsdoc.js" type="text/javascript"></script> <script src="MicrosoftAjax.js" type="text/javascript"></script> <script src="DataService.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> function GetService() { return new Sys.Data.DataService("/NorthwindService.svc"); } $(function() { $("#query").click(function() { //发起一个异步查询 var proxy = GetService(); var query = "/Customers()"; //这里构造的查询字符串可以很复杂 proxy.query(query, function(result, context) { for (idx in result) { var customer = result[idx]; $("<li>" + customer.CustomerID + "," + customer.CompanyName + "</li>").appendTo("#result"); } }); }); $("#insert").click(function() { //插入一个新的客户 var proxy = GetService(); var customer = { CustomerID: "ABCDE", CompanyName: "Thinker Inc" }; proxy.insert(customer, "/Customers", function(result) { alert("操作已经成功"); }); }); $("#update").click(function() { //更新一个客户 var proxy = GetService(); var customer; proxy.query("/Customers('ABCDE')", function(result) { customer = result; //修改这个customer customer.CompanyName = "Changed"; proxy.update(customer, null, function(result) { alert("更新成功"); }); }); }); $("#delete").click(function() { //删除一个客户 var proxy = GetService(); var customerID = "ABCDE"; proxy.remove(null, "/Customers('" + customerID + "')", function(result) { alert("删除成功"); }); }); }); </script> </head> <body> <form id="form1" runat="server"> <div> <input type="button" value="查询" id="query" /> <input type="button" value="插入" id="insert" /> <input type="button" value="更新" id="update" /> <input type="button" value="删除" id="delete" /> </div> <ol id="result"> </ol> </form> </body> </html>
注意,这个DataService.js是单独的,它实际上是封装了四个操作
//------------------------------------------------------------------------------ // <copyright file="DataService.js" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ Type.registerNamespace('Sys.Data'); Sys.Data.ActionResult = function(result, error, actionContext, operation) { /// <summary>Represents the result of a single operation in an action sequence batch.</summary> /// <param name="result" mayBeNull="true">Result (if any) of the operation.</param> /// <param name="error" mayBeNull="true" type="Sys.Data.DataServiceError">Error that occurred during the operation.</param> /// <param name="actionContext" mayBeNull="true">Context object passed to the executor.</param> /// <param name="operation" type="String">Short description of the operation performed.</param> this._result = result; this._error = error; this._actionContext = actionContext; this._operation = operation; } Sys.Data.ActionResult.prototype = { /* * PROPERTIES */ get_result: function() { /// <summary>Gets the result (if any) of the operation.</summary> /// <value mayBeNull="true">Operation result.</value> return this._result; }, get_error: function() { /// <summary>Gets the error that occurred during the operation. Returns null if no error occurred.</summary> /// <value mayBeNull="true" type="Sys.Data.DataServiceError">Operation error.</value> return this._error; }, get_actionContext: function() { /// <summary>Gets the context object passed to the executor.</summary> /// <value mayBeNull="true">Operation context object.</value> return this._actionContext; }, get_operation: function() { /// <summary>Gets a short description of the operation performed.</summary> /// <value type="String">Operation description.</value> return this._operation; } }; Sys.Data.ActionResult.registerClass("Sys.Data.ActionResult"); Sys.Data.ActionSequence = function(dataService) { /// <summary>Exposes methods for performing batch operations against a web-based data service.</summary> /// <param name="dataService" type="Sys.Data.DataService">The DataService object against which to perform operations.</param> this._dataService = dataService; this._actionQueue = new Array(); } Sys.Data.ActionSequence.prototype = { /* * PROPERTIES */ get_service: function() { /// <summary>Gets the DataService object against which operations are performed.</summary> /// <value type="Sys.Data.DataService">The DataService.</value> return this._dataService; }, /* * METHODS */ addInsertAction: function(item, resourceSetUri, actionContext) { /// <summary>Adds an insertion to the execution queue.</summary> /// <param name="item" type="Object">Item to insert.</param> /// <param name="resourceSetUri" type="String" mayBeNull="true">Resource set into which the item should be inserted.</param> /// <param name="actionContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> var dataService = this._dataService; Array.enqueue(this._actionQueue, function(o) { dataService.insert( item, resourceSetUri, Sys.Data.ActionSequence._genSuccessCallback(o), Sys.Data.ActionSequence._genFailureCallback(o), actionContext // userContext (per-action) )}); }, addUpdateAction: function(item, resourceUri, actionContext) { /// <summary>Adds an update to the execution queue.</summary> /// <param name="item" type="Object">Item to update.</param> /// <param name="resourceUri" type="String" mayBeNull="true" optional="true">Resource set in which the item should be updated.</param> /// <param name="actionContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> var dataService = this._dataService; Array.enqueue(this._actionQueue, function(o) { dataService.update( item, resourceUri, Sys.Data.ActionSequence._genSuccessCallback(o), Sys.Data.ActionSequence._genFailureCallback(o), actionContext // userContext (per-action) )}); }, addRemoveAction: function(item, resourceUri, actionContext) { /// <summary>Adds a removal to the execution queue.</summary> /// <param name="item" type="Object" mayBeNull="true">Item to remove.</param> /// <param name="resourceUri" type="String" mayBeNull="true" optional="true">Resource set from which the item should be removed.</param> /// <param name="actionContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> var dataService = this._dataService; Array.enqueue(this._actionQueue, function(o) { dataService.remove( item, resourceUri, Sys.Data.ActionSequence._genSuccessCallback(o), Sys.Data.ActionSequence._genFailureCallback(o), actionContext // userContext (per-action) )}); }, clearActions : function() { /// <summary>Clears the action queue.</summary> Array.clear(this._actionQueue); }, executeActions: function(actionsCallback, userContext) { /// <summary>Executes operations in the action queue.</summary> /// <param name="actionsCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon completion of all operations.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this batch.</param> // state object for internal callback methods var o = { actionResultQueue: new Array(), hasError: false, remainingActions: this._actionQueue }; // break reference to array so user can't modify after kickoff this._actionQueue = new Array(); // kickoff - ensure final callback is asynchronous so as not to break method contract Array.enqueue(o.remainingActions, function(o) { if (actionsCallback) { window.setTimeout(function() { actionsCallback(o.actionResultQueue, o.hasError, userContext); }, 0); } }); Array.dequeue(o.remainingActions)(o); } } /* * STATIC INTERNAL HELPER METHODS */ // generates an onSuccess callback Sys.Data.ActionSequence._genSuccessCallback = function(o) { return function(result, actionContext, operation) { var newAR = new Sys.Data.ActionResult(result, null, actionContext, operation); Array.enqueue(o.actionResultQueue, newAR); Array.dequeue(o.remainingActions)(o); // kickoff next function }; }; // generates an onFailure callback Sys.Data.ActionSequence._genFailureCallback = function(o) { return function(error, actionContext, operation) { o.hasError = true; var newAR = new Sys.Data.ActionResult(null, error, actionContext, operation); Array.enqueue(o.actionResultQueue, newAR); Array.dequeue(o.remainingActions)(o); // kickoff next function }; }; Sys.Data.ActionSequence.registerClass("Sys.Data.ActionSequence"); Sys.Data.DataService = function(serviceUri) { /// <summary>Exposes methods for interacting with a web-based data service.</summary> /// <param name="serviceUri" type="String">URI (absolute or relative) of the data service.</param> this._serviceUri = serviceUri; this._timeout = 0; this._defaultUserContext = null; this._defaultSucceededCallback = null; this._defaultFailedCallback = null; } Sys.Data.DataService.prototype = { /* * PROPERTIES */ get_serviceUri: function() { /// <summary>Gets the URI of the data service.</summary> /// <value type="String">The URI of the data service.</value> return this._serviceUri; }, get_timeout: function() { /// <summary>Gets the timeout period of each operation.</summary> /// <value type="Number" integer="true">The timeout period (in milliseconds) for each operation.</value> if (this._timeout === 0) { return Sys.Net.WebRequestManager.get_defaultTimeout(); } return this._timeout; }, set_timeout: function(value) { this._timeout = value; }, get_defaultUserContext: function() { /// <summary>Gets the default user context (state object) of each operation.</summary> /// <value mayBeNull="true">The default user context for each operation.</value> return this._defaultUserContext; }, set_defaultUserContext: function(value) { this._defaultUserContext = value; }, get_defaultSucceededCallback: function() { /// <summary>Gets the default callback executed after each successful operation.</summary> /// <value type="Function" mayBeNull="true">The default success callback for each operation.</value> return this._defaultSucceededCallback; }, set_defaultSucceededCallback: function(value) { this._defaultSucceededCallback = value; }, get_defaultFailedCallback: function() { /// <summary>Gets the default callback executed after each unsuccessful operation.</summary> /// <value type="Function" mayBeNull="true">The default failure callback for each operation.</value> return this._defaultFailedCallback; }, set_defaultFailedCallback: function(value) { this._defaultFailedCallback = value; }, /* * METHODS */ query: function(query, succeededCallback, failedCallback, userContext, webRequest) { /// <summary>Performs a query (read) against the data service.</summary> /// <param name="query" type="String" mayBeNull="true" optional="true">Path to query.</param> /// <param name="succeededCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon successful completion of the operation.</param> /// <param name="failedCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon unsuccessful completion of the operation.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> /// <param name="webRequest" type="Sys.Net.WebRequest" mayBeNull="true" optional="true">A WebRequest object to use for this operation.</param> var wRequest = this._prepWebRequest(null, query, "GET", succeededCallback, failedCallback, userContext, query, webRequest); wRequest.invoke(); }, loadProperty: function(item, property, succeededCallback, failedCallback, userContext, webRequest) { /// <summary>Populates the property of a given item.</summary> /// <param name="item" type="Object">Item containing the property to be populated.</param> /// <param name="property" type="String">Name of the property which should be populated.</param> /// <param name="succeededCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon successful completion of the operation.</param> /// <param name="failedCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon unsuccessful completion of the operation.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> /// <param name="webRequest" type="Sys.Net.WebRequest" mayBeNull="true" optional="true">A WebRequest object to use for this operation.</param> var succeededHelper = function(result, context, operation) { item[operation] = result; if (!succeededCallback) { succeededCallback = this._defaultSucceededCallback; } if (succeededCallback) { succeededCallback(item, context, operation); } }; var uri; if (item[property] && item[property].__metadata && item[property].__metadata.uri) { uri = item[property].__metadata.uri; } else if (item.__metadata && item.__metadata.uri) { uri = item.__metadata.uri + '/' + property; } else { throw Error.create(Sys.Data.Res.dataServiceLoadPropertyUriNotPresent); } var wRequest = this._prepWebRequest(null, uri, "GET", succeededHelper, failedCallback, userContext, property, webRequest); wRequest.invoke(); }, insert: function(item, resourceSetUri, succeededCallback, failedCallback, userContext, webRequest) { /// <summary>Performs an insertion against the data service.</summary> /// <param name="item" type="Object">Item to insert.</param> /// <param name="resourceSetUri" type="String" mayBeNull="true">Resource set into which the item should be inserted.</param> /// <param name="succeededCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon successful completion of the operation.</param> /// <param name="failedCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon unsuccessful completion of the operation.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> /// <param name="webRequest" type="Sys.Net.WebRequest" mayBeNull="true" optional="true">A WebRequest object to use for this operation.</param> var wRequest = this._prepWebRequest(null, resourceSetUri, "POST", succeededCallback, failedCallback, userContext, "insert", webRequest); // moved serialization logic out since we ignore metadata wRequest.set_body(Sys.Serialization.JavaScriptSerializer.serialize(item)); wRequest.get_headers()["Content-Type"] = "application/json"; wRequest.invoke(); }, update: function(item, resourceUri, succeededCallback, failedCallback, userContext, webRequest) { /// <summary>Performs an update against the data service.</summary> /// <param name="item" type="Object">Item to update.</param> /// <param name="resourceUri" type="String" mayBeNull="true">Resource set in which the item should be updated.</param> /// <param name="succeededCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon successful completion of the operation.</param> /// <param name="failedCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon unsuccessful completion of the operation.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> /// <param name="webRequest" type="Sys.Net.WebRequest" mayBeNull="true" optional="true">A WebRequest object to use for this operation.</param> var wRequest = this._prepWebRequest(item, resourceUri, "PUT", succeededCallback, failedCallback, userContext, "update", webRequest); wRequest.get_headers()["Content-Type"] = "application/json"; wRequest.invoke(); }, remove: function(item, resourceUri, succeededCallback, failedCallback, userContext, webRequest) { /// <summary>Performs a removal against the data service.</summary> /// <param name="item" type="Object" mayBeNull="true">Item to remove.</param> /// <param name="resourceUri" type="String" mayBeNull="true" optional="true">Resource set from which the item should be removed.</param> /// <param name="succeededCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon successful completion of the operation.</param> /// <param name="failedCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon unsuccessful completion of the operation.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> /// <param name="webRequest" type="Sys.Net.WebRequest" mayBeNull="true" optional="true">A WebRequest object to use for this operation.</param> if (!((item && item.__metadata && item.__metadata.uri) || resourceUri)) { // must specify URI in item metadata or as parameter throw Error.create(Sys.Data.Res.dataServiceRemoveUriNotPresent); } var wRequest = this._prepWebRequest(item, resourceUri, "DELETE", this._cbReplaceResult(succeededCallback, null) /* don't return any object to success callback */, failedCallback, userContext, "remove", webRequest); // we can't actually serialize an item when we perform a removal delete wRequest.get_headers()["Content-Type"]; wRequest.set_body(null); wRequest.invoke(); }, invoke: function(operationUri, httpVerb, parameters, succeededCallback, failedCallback, userContext, webRequest) { /// <summary>Invokes a method exposed by the data service.</summary> /// <param name="operationUri" type="String">Path to the service operation to invoke.</param> /// <param name="httpVerb" type="String" maybeNull="true" optional="true">HTTP verb to be used for this service call.</param> /// <param name="parameters" type="Object" maybeNull="true" optional="true">Dictionary of parameters to be passed to the service method.</param> /// <param name="succeededCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon successful completion of the operation.</param> /// <param name="failedCallback" type="Function" mayBeNull="true" optional="true">Callback to execute upon unsuccessful completion of the operation.</param> /// <param name="userContext" mayBeNull="true" optional="true">A context object associated with this operation.</param> /// <param name="webRequest" type="Sys.Net.WebRequest" mayBeNull="true" optional="true">A WebRequest object to use for this operation.</param> var qb = new Sys.Data.QueryBuilder(operationUri); for (key in parameters) { qb.get_queryParams()[encodeURIComponent(key)] = encodeURIComponent(parameters[key]); } var wRequest = this._prepWebRequest(null, qb.toString(), httpVerb, succeededCallback, failedCallback, userContext, operationUri, webRequest); if (httpVerb == "POST") { // prevents CSRF (SQLBUDT 554530) wRequest.get_headers()["X-Service-Post"] = "true"; } wRequest.invoke(); }, createActionSequence: function() { /// <summary>Creates a new action sequence for execution against this data service.</summary> /// <returns type="Sys.Data.ActionSequence">An ActionSequence object.</returns> return new Sys.Data.ActionSequence(this); }, /* * INTERNAL HELPER FUNCTIONS */ // common code for preparing a WebRequest _prepWebRequest: function(item, relUri, verb, onSuccess, onFailure, context, operation, wRequest) { if (!relUri) { relUri = ""; } if (!wRequest) { wRequest = new Sys.Net.WebRequest(); } wRequest.set_url(Sys.Data.DataService._concatUris(this._serviceUri, relUri)); wRequest.set_httpVerb(verb); wRequest.set_timeout(this.get_timeout()); var headers = wRequest.get_headers(); headers["Accept"] = "application/json"; if (item) { wRequest.set_body(Sys.Serialization.JavaScriptSerializer.serialize(item)); headers["Content-Type"] = "application/json"; if (item.__metadata && item.__metadata.uri) wRequest.set_url(item.__metadata.uri); } // set defaults if (!onSuccess) { onSuccess = this._defaultSucceededCallback; } if (!onFailure) { onFailure = this._defaultFailedCallback; } if (!context) { context = this._defaultUserContext; } wRequest.add_completed(function(executor, eventArgs) { Sys.Data.DataService._callbackHelper(executor, eventArgs, onSuccess, onFailure, context, operation); }); return wRequest; }, // helper to replace the result object for callbacks _cbReplaceResult: function(cb, retVal) { if (!cb) { cb = this._defaultSucceededCallback; } return (cb) ? function(result, context, operation) { cb(retVal, context, operation); } : null; } } /* * STATIC INTERNAL HELPER FUNCTIONS */ // concatenation of URIs Sys.Data.DataService._concatUris = function(serviceUri, resourceUri) { if (serviceUri.endsWith('/')) { serviceUri = serviceUri.substr(0, serviceUri.length - 1); } if (resourceUri.startsWith('/')) { resourceUri = resourceUri.substr(1); } return serviceUri + '/' + resourceUri; }; // heavily modified preexisting WebServiceProxy code handles deserialization of data service responses Sys.Data.DataService._callbackHelper = function(executor, eventArgs, onSuccess, onFailure, userContext, operation) { if (executor.get_responseAvailable()) { var statusCode = executor.get_statusCode(); // works around an IE bug where 204 responses to PUT requests get turned into 1223 errors. if (statusCode == 1223) { statusCode = 204; } var result = null; try { var contentType = executor.getResponseHeader("Content-Type"); if (contentType.startsWith("application/json")) { result = executor.get_object(); } else if (contentType.startsWith("text/xml")) { result = executor.get_xml(); } // Default to the executor text else { result = executor.get_responseData(); } } catch (ex) { } var error = executor.getResponseHeader("jsonerror"); var errorObj = (error === "true"); if (errorObj) { if (result) { result = new Sys.Data.DataServiceError(false, result.Message, result.StackTrace, result.ExceptionType); } } else if (contentType.startsWith("application/json")) { if (!result || typeof(result.d) === "undefined") { throw Sys.Data.DataService._createFailedError(operation, String.format("The data operation '{0}' returned invalid data. The JSON wrapper is incorrect.", operation)); } result = result.d; } if (((statusCode < 200) || (statusCode >= 300)) || errorObj) { if (onFailure) { if (!result || !errorObj) { result = new Sys.Data.DataServiceError(false /*timedout*/, String.format("The data operation '{0}' failed.", operation), "", ""); } result._statusCode = statusCode; onFailure(result, userContext, operation); } // #if DEBUG else { // In debug mode, if no error was registered, display some trace information if (result && errorObj) { // If we got a result, we're likely dealing with an error in the method itself error = result.get_exceptionType() + "-- " + result.get_message(); } else { // Otherwise, it's probably a 'top-level' error, in which case we dump the // whole response in the trace error = executor.get_responseData(); } throw Sys.Data.DataService._createFailedError(operation, String.format("The data operation '{0}' failed with the following error: {1}", operation, error)); } // #endif } else if (onSuccess) { onSuccess(result, userContext, operation); } } else { var msg; if (executor.get_timedOut()) { msg = String.format("The data operation '{0}' timed out.", operation); } else { msg = String.format("The data operation '{0}' failed.", operation) } if (onFailure) { onFailure(new Sys.Data.DataServiceError(executor.get_timedOut(), msg, "", ""), userContext, operation); } // #if DEBUG else { // In debug mode, if no error was registered, display some trace information throw Sys.Data.DataService._createFailedError(operation, msg); } // #endif } }; //#if DEBUG Sys.Data.DataService._createFailedError = function(operation, errorMessage) { var displayMessage = "Sys.Data.DataServiceFailedException: " + errorMessage; var e = Error.create(displayMessage, { 'name': 'Sys.Data.DataServiceFailedException', 'operation': operation }); e.popStackFrame(); return e; } //#endif Sys.Data.DataService.registerClass("Sys.Data.DataService"); Sys.Data.DataServiceError = function(timedOut, message, stackTrace, exceptionType) { /// <summary>Represents a web-based data service error.</summary> /// <param name="timedOut" type="Boolean">Whether the operation failed because of a timeout.</param> /// <param name="message" type="String" mayBeNull="true">The error message.</param> /// <param name="stackTrace" type="String" mayBeNull="true">The stack trace of the error.</param> /// <param name="exceptionType" type="String" mayBeNull="true">The server exception type.</param> this._timedOut = timedOut; this._message = message; this._stackTrace = stackTrace; this._exceptionType = exceptionType; this._statusCode = -1; } Sys.Data.DataServiceError.prototype = { /* * PROPERTIES */ get_timedOut: function() { /// <summary>True if the data service operation failed due to timeout.</summary> /// <value type="Boolean">Whether the operation failed due to timeout.</value> return this._timedOut; }, get_statusCode: function() { /// <summary>HTTP status code of the response if any, defaults to -1 otherwise</summary> /// <value type="Number">Int representing the status of the response.</value> return this._statusCode; }, get_message: function() { /// <summary>Error message</summary> /// <value type="String">Error message</value> return this._message; }, get_stackTrace: function() { /// <summary>Stack trace of the error</summary> /// <value type="String">Stack trace of the error.</value> return this._stackTrace; }, get_exceptionType: function() { /// <summary>Exception type of the error</summary> /// <value type="String">Exception type of the error.</value> return this._exceptionType; } } Sys.Data.DataServiceError.registerClass("Sys.Data.DataServiceError"); Sys.Data.QueryBuilder = function(uri) { /// <summary>Allows construction of ADO.NET Data Service queries.</summary> /// <param name="uri" type="String">The URI (absolute or relative) to parse.</param> this._queryparams = new Object(); this._uri = uri; var idxQuery = uri.indexOf('?'); if (idxQuery >= 0) { // split query string if already exists this._uri = uri.substr(0, idxQuery); var params = uri.substr(idxQuery + 1).split('&'); for (var i in params) { param = params[i]; var idxValue = param.indexOf('='); if (idxValue >= 0) { this._queryparams[param.substr(0, idxValue)] = param.substr(idxValue + 1); } else { this._queryparams[param] = ""; } } } } Sys.Data.QueryBuilder.prototype = { /* * PROPERTIES */ get_skip: function() { /// <summary>Gets the starting index at which elements should be returned.</summary> /// <value type="Number" integer="true" mayBeNull="true">The number of elements to skip when returning results, /// or null if no skip value is specified.</value> return this._getIntParam("$skip"); }, set_skip: function(value) { this._setParam("$skip", value); }, get_top: function() { /// <summary>Gets the maximum number of elements to return.</summary> /// <value type="Number" integer="true" mayBeNull="true">The maximum number of elements to return, /// or null if no maximum is specified.</value> return this._getIntParam("$top"); }, set_top: function(value) { this._setParam("$top", value); }, get_orderby: function() { /// <summary>Gets the ordering string that should be applied to the result set.</summary> /// <value type="String" mayBeNull="true">The ordering applied to the result set, /// or null if no ordering is specified.</value> return this._getStringParam("$orderby"); }, set_orderby: function(value) { this._setParam("$orderby", value); }, get_filter: function() { /// <summary>Gets the filter string that should be applied to the result set.</summary> /// <value type="String" mayBeNull="true">The filter applied to the result set, /// or null if no filter is specified.</value> return this._getStringParam("$filter"); }, set_filter: function(value) { this._setParam("$filter", value); }, get_expand: function() { /// <summary>Gets the property expansion string that should be applied to the result set.</summary> /// <value type="String" mayBeNull="true">The property expansion applied to the result set, /// or null if no property expansion is specified.</value> return this._getStringParam("$expand"); }, set_expand: function(value) { this._setParam("$expand", value); }, get_resourcePath: function() { /// <summary>Gets the resource path (without query parameters) originally passed as an argument to /// this object's constructor.</summary> /// <value type="string">The resource path of this QueryBuilder object.</value> return this._uri; }, /* setter temporarily removed until we can figure out how to spec it set_resourcePath: function(value) { var idxQuery = value.indexOf('?'); this._uri = (idxQuery >= 0) ? value.substr(0, idxQuery) : value; }, */ get_queryParams: function() { /// <summary>Gets the dictionary of query parameters for the current QueryBuilder.</summary> /// <value type="Object">A dictionary of query parameters. This object will be non-null but may /// contain no fields if no query parameters have been set.</value> return this._queryparams; }, /* * METHODS */ toString: function() { /// <summary>Generates a complete query string based on this object's resource path and parameter dictionary.</summary> /// <returns type="string">The complete query string.</returns> var params = new Array(); for (var key in this._queryparams) { if (!Array.contains(Sys.Data.QueryBuilder._queryOptions, key)) { var value = this._queryparams