Wednesday, March 28, 2012

PageMethods and xml-script?

So, I've only seen a couple posts that touch on this, and none had a direct answer. What I'm looking to do is to call one of my pages' WebMethods using the declarative syntax. I'm not sure exactly how to do that.

Using javascript it works fine, so I know that I have the rest of the thing set up right, but for whatever reason using all the components and bindings and all that just.

Conversely, I tried doing it with just a regular web service and binding,a nd that works fine too. Anyone successfully use declarative markup with WebMethods that are served from the aspx page?

hello.

currently, you can only do that if you call web service methods, you can, however, develop your own class which could be used from xml-script (you can adapt the ServiceMethodRequest to do that).


I'm not sure, I guess, what differentiates a webmethod called from the codefile from a webmethod called from a web service, in the eyes of xml-script. What is the body of code that influences the xml-script schema? I assume it's one of the classes in atlas.js, but I'm not sure which one. I'm interested in hearing how you'd do it if it were your task, though.

thanks,

Paul


hello.

take a look at the servicemethodrequest class. you just have to build a similar class but instead of using the servicemethod class internally, you should use teh pagemethod class.


Oh, I see. yeah, I spent the last half hour or so just reading (again) the atlas.js source. I'm not as sharp in javascript as I am in server-side stuff, but I'm starting to get the flow. thanks for the tip, if I end up implementing this I'll post the results.

Wow, ok, that was a LOT easier than I thought it would be. Thanks for the tip. Code follows. I went ahead and put it in my namespace b/c I didn't want to pollute teh Sys.Net namespace, but feel free to take, modify, whatever at liberty. As you suggested, the main thing to do here was to take the existing ServiceMethodRequest class and swap out the ServiceMethod references for PageMethod ones. I also pulled otu some of the member variables that I knew I wouldn't need (e.g. url-related ones) to tidy it up. This is a first draft, so I might find more that I want to do now that I have my teeth in it.

Thanks again!!

Paul

/*

Title: PageMethodExtender.js

Author: Paul Vencill

Summary: Add-on class to Atlas that will allow web methods exposed in the page's codefile to be called from the page's xml-script.

*/

Type.registerNamespace(

'Com');

Type.registerNamespace(

'Com.VelocityDataSolutions');

Com.VelocityDataSolutions.PageMethodRequest =

function() {

Com.VelocityDataSolutions.PageMethodRequest.initializeBase(

this);var _methodName =null;var _parameters =null;var _response =null;var _userContext =null;var _result =null;var _request =null;var _timeoutInterval = 0;var _priority = Sys.Net.WebRequestPriority.Normal;this.get_url =function() {return _url;

}

this.set_url =function(value) {

_url = value;

}

this.get_appUrl =function() {return _appUrl;

}

this.set_appUrl =function(value) {

_appUrl = value;

}

this.get_methodName =function() {return _methodName;

}

this.set_methodName =function(value) {

_methodName = value;

}

this.get_parameters =function() {if (_parameters ==null) {

_parameters = { };

}

return _parameters;

}

this.get_response =function() {return _response;

}

this.get_result =function() {return _result;

}

this.get_timeoutInterval =function() {return _timeoutInterval;

}

this.set_timeoutInterval =function(value) {

_timeoutInterval = value;

}

this.get_priority =function() {return _priority;

}

this.set_priority =function(value) {

_priority = value;

}

this.completed =this.createEvent();this.timeout =this.createEvent();this.error =this.createEvent();this.aborted =this.createEvent();this.invoke =function(userContext) {if (_request !=null) {returnfalse;

}

var _pageMethod =new Sys.Net.PageMethod(_methodName);

_request = _pageMethod.invoke(_parameters, onMethodComplete, onMethodTimeout,

onMethodError, onMethodAborted,

this ,

_timeoutInterval, _priority);

function onMethodComplete(result, response, target ) {

_request =

null;

_userContext = userContext;

_response = response;

_result = result;

target.completed.invoke(target, Sys.EventArgs.Empty);

}

function onMethodError(result, response, target ) {

_request =

null;

_userContext = userContext;

_response = response;

_result = result;

target.error.invoke(target, Sys.EventArgs.Empty);

}

function onMethodTimeout(request, target ) {

_request =

null;

_userContext = userContext;

target.timeout.invoke(request, Sys.EventArgs.Empty);

}

function onMethodAborted(request, target ) {

_request =

null;

_userContext = userContext;

target.aborted.invoke(request, Sys.EventArgs.Empty);

}

returntrue;

}

this.abort =function() {if (_request) {

_request.abort();

}

}

this.getDescriptor =function() {var td = Com.VelocityDataSolutions.PageMethodRequest.callBaseMethod(this,'getDescriptor');

td.addProperty(

'methodName', String);

td.addProperty(

'parameters', Object,true);

td.addProperty(

'response', Sys.Net.WebRequestExecutor,true);

td.addProperty(

'result', Object,true);

td.addProperty(

'timeoutInterval', Number);

td.addProperty(

'priority', Number);

td.addMethod(

'invoke');

td.addMethod(

'abort');

td.addEvent(

'completed',true);

td.addEvent(

'timeout',true);

td.addEvent(

'error',true);

td.addEvent(

'aborted',true);return td;

}

Com.VelocityDataSolutions.PageMethodRequest.registerBaseMethod(

this,'getDescriptor');

}

Com.VelocityDataSolutions.PageMethodRequest.registerClass(

' Com.VelocityDataSolutions.PageMethodRequest', Sys.Component);

Sys.TypeDescriptor.addType(

'script','pageMethod', Com.VelocityDataSolutions.PageMethodRequest);

cool!

that's the spirit :)


Hi,

thanks for posting the code, Paul.

Glad to, I'm very excited about this. I also went ahead and built a Page subclass that inserts a ScriptManager control if there isn't one and pulls in the xml-script from an external file (by default located in the same folder and with the same name as the parent document but with a .ascr extension.). Here's teh code for that subclass as well. It works, but I'm still polishing it to make it a little more robust, add comments, etc etc. I just wanted to see if i could hack my way through it.

using

System;

using

System.Web.UI;

//using System.Xml;

using

System.Xml.XPath;

///

<summary>

///

Summary description for AtlasPage

///

</summary>

public

classAtlasPage : System.Web.UI.Page

{

privatestring _xmlScript;privatebool _hasScriptManager;protectedoverridevoid OnInit(EventArgs e)

{

addScriptManager();

addAtlasScript();

base.OnInit(e);

}

protectedstring _scriptFile;publicstring ScriptFile

{

get {return _scriptFile; }set { _scriptFile =value; }

}

privatevoid getXmlScript()

{

if(String.IsNullOrEmpty(_scriptFile))

{

string url = Request.Url.ToString();

url = url.Replace(

".aspx",".ascr");

_scriptFile = url;

}

try

{

XPathDocument xdoc =newXPathDocument(_scriptFile);XPathNavigator xNav = xdoc.CreateNavigator();

xNav.Select(

"script");

_xmlScript =

String.Format("\n{0}\n",xNav.OuterXml.ToString());

}

catch

{

_xmlScript =

String.Format(@."<!-- File not found: {0} -->","xml-script");

}

}

privatevoid addAtlasScript()

{

getXmlScript();

LiteralControl lit =newLiteralControl(_xmlScript);this.Controls.AddAt(this.Controls.Count - 1, lit);

}

privatevoid addScriptManager()

{

_hasScriptManager =

false;

iterateCollection(Controls);

if (!_hasScriptManager)

{

Microsoft.Web.UI.

ScriptManager scm =new Microsoft.Web.UI.ScriptManager();this.Header.Controls.Add(scm);

}

}

privatevoid iterateCollection(ControlCollection ctrls)

{

foreach (Control ctrlin ctrls)

{

if (ctrl.HasControls())

{

iterateCollection(ctrl.Controls);

}

if (ctrl.ToString().Contains("ScriptManager"))

{ _hasScriptManager =

true; }

}

}

}

Paul Vencill

Velocity Data Solutions. LLC

www.velocitydatasolutions.com

No comments:

Post a Comment