Showing posts with label figure. Show all posts
Showing posts with label figure. Show all posts

Wednesday, March 28, 2012

Calling a Web Service from within JavaScript source

I'm trying to make an internal Web Service call from within an ATLAS client control, but I can't figure out how to get the parameters passed into the call properly into the Invoke method for ServiceMethod.

The following manages to call the Web Service but the parameter is not respected.

var num =new Object();

num.Value = -1;

var serviceMethod =new Sys.Net.ServiceMethod(_serviceURL, _serviceMethod,null/*? _appUrl */);var _request = serviceMethod.invoke(num, _onMethodComplete, _onError,

_onError,_onError,

this,

2000, Sys.Net.WebRequestPriority.Normal);

Actually I can see that the object needs to be formatted with the name of the parameter. While I can do this for testing - at runtime I have no idea what service the user is connecting to so I won't know the name of the parameter. Isn't there some more generic way to call the Web Service from code?

Also what is AppUrl in this context?

I suspect the answer is the higher level ServiceMethodRequest, but it takes a UserContext object that I have no idea how to create.

Any ideas appreciated.

+++ Rick --

The first parameter to invoke() is an object that wraps all the parameters of your server method. e.g if your server method takes an int named 'n' and a string named 's', you would have:

serviceMethod.invoke({i:5, s:"Hello"), ...)

David


Ok, that's not terribly useful <g>... All of the values passed are going to be variables. Unless I parse this myself I can't see how to call the service dynamically with this scheme.

There's gotta be a higher level mechanism for making a remote Web Service call? If not, then that's something that should maybe be there? Similar to what Callmethod used to do?

+++ Rick --


Not sure I'm following you. In the code above, you can replace 5 and "Hello" by arbitrary variables.

Note that there is indeed an alternative way of calling services by using the generated proxy. See thispage for an example.


Yeah of course I can call a Web Service that's PREDEFINED using the proxy class generated, but that doesn't help if you need to call the service when you don't know beforehand what the name is or what's exposed on it. If you want dynamic execution you won't know immediately at runtime what the parameters are or what the type.

So yeah, I can write a string value there but if I don't know that it's a string beforehand it gets to be a major hassle to write that call.

Consider this scenario: You build a custom client control and you have an option to call a service Url with arbitrary parameters that are set up in an array. Then you have to parse that call into this funky syntax.

There needs to be a way to dynamically call a service the same way that CallMethod used to work.


Yeah of course I can call a Web Service that's PREDEFINED using the proxy class generated, but that doesn't help if you need to call the service when you don't know beforehand what the name is or what's exposed on it. If you want dynamic execution you won't know immediately at runtime what the parameters are or what the type.

So yeah, I can write a string value there but if I don't know that it's a string beforehand it gets to be a major hassle to write that call.

Consider this scenario: You build a custom client control and you have an option to call a service Url with arbitrary parameters that are set up in an array. Then you have to parse that call into this funky syntax.It doesn't work.

There needs to be a way to dynamically call a service the same way CallMethod used to work. So you can specify an array of values, an endpoint Url and method name.


I do not think Macrh CTP directly provides the functionality you are looking for. But if you can exam how Sys.Data.DataSource class works. it may provide some hints if you decide to write you own class to accomplish your goal.

Actually, the syntax above is completely generic, and requires no hard coded knowledge of any aspect of the web service. All the parameters are passed as arbitrary name/value pairs on a standard Javascript object, which can be added dynamically.

David


David, I think your sample code is some kind of generic, but i don't see how it works if we don't know , at design time, what public web services out there user want to call.


Why do you think you need to have this information at design time? Every piece of the code (the URL, the method name, the parameter names and values) can be specified dynamically.

Of course, if you are referring to the proxy class, then yes, that is only usable for the case where you know at design time what service you want to call. But the original post was not about the proxy.

David


Hi David,

We seem to have some sort of disconnect here. Let me explain what I mean.

You said:

The first parameter to invoke() is an object that wraps all the parameters of your server method. e.g if your server method takes an int named 'n' and a string named 's', you would have:

serviceMethod.invoke({i:5, s:"Hello"), ...)

First is that type prefix required or not? I think I tried without it and it didn't seem to work. If it is required then the above is not generic because you'd have to parse the values into the above format and then eval it into a string somehow which is a mess.

You say the above with such certainty, but you have to remember we're working off this stuff blind. This stuff isn't documented. We DON'T KNOW what the parameter signature is, we have to guess...

So anything you can do to explain would be really helpful...

Thanks,

+++ Rick --


Hi Rick,

In Javascript writing { i:5, s:"hello" } creates an object that contains two fields with those name/value pairs. 'i' and 's' are not prefixes, they are field names, and in Atlas JSON services (as in SOAP) they are required since parameters are passed by name (and not by order).

Another way to create this same object is to write:

var o = {};
o.i = 5;
o.s = "hello";

And yet another way which I think will be the one you want is:

var o = {};
o["i"] = 5;
o["s"] = "hello";

Note that that there is no need to call eval(), which would indeed be ugly (and inefficient). Does that give you what you are lookin for?

And I certainly realize the doc is poor and samples are limited. But they'll get better! :)

David

Monday, March 26, 2012

Call JS at end of UpdatePanels content loading

I'm trying to figure out how to call a javascript method at the end of an UpdatePanel's content reloading. I know this must be possible, but I'm not seeing how yet.

Here's what I have: one page with an update panel. Contained within the update panel is a series of controls, much like a wizard. Each control has a button that posts back to the server, which then loads a different control. By using the UpdatePanel, the postback is hidden, which is nice. What I want is for every time the control within the UpdatePanel is changed for some custom javascript to run. The script just resets a page-scoped timer that notifies the user his session is about to expire. How can I hook in to the postback and run my one line of script? Thanks.

Of course after hours of searching and posting I finally find an example using the PageRequestManager that does the trick nicely. For the record, the simple script was:

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args)
{ extendSession();// My JS method }