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

No comments:

Post a Comment