Javascript

Instantiating Server-Side Objects From the Client Using ASP.NET AJAX


March 3, 2008 08:40 by joel

The topic for this post grew out of a number of conversations I've had in recent weeks on subjects relating to WebMethods. For the purposes of this post, I'm going to focus on the the more specific subject of instantiating server-side objects from the client. Although it is a relatively simple thing to accomplish, I think it provides something very tangible and useful to use a starting point for understanding the different ways that the ASP.NET AJAX framework simplifies the exchange of data between the client and the server. 

To begin, I'm going to fire up Visual Studio and create a new ASP.NET 3.5 website (note, however, that everything I am going to do in this post works pretty much the same in ASP.NET 2.0 with the AJAX framework installed). The first step is to define the class which we want to instantiate from the client. Let's use a person as an example. We'll give the class Name, Age, and Weight properties :

Class Screen Shot

Note that I've used a shortcut provided by C#3.0. If your getter and setter don't require any additional logic, you can simply declare your properties as I did for this class. It is just a shortcut provided by the compiler, and the underlying CIL will be exactly the same as if you had defined the properties in the old way, using private variables and getter/setter methods.

The next step is to create a WebService. To keep things simple, the WebMethod will take a Person object as an argument and will return a string.

WebService

The cool thing about this is that since the method takes a Person as an argument, once you register the WebService with the ScriptManager, the client will automatically have a definition of Person. In fact, with VS2008, you'll even get intellisense for it. So for this example, instantiating a Person on the client is as simple as creating a new object, like so:   

the js

All I'm going to do to demonstrate this is call the HelloWorld method, passing it the Person object which I created. In the callback function, I'll simply pass the returned string to an alert: 

the demo

If you try this out, you'll see that as you might expect, you get an alert which says "Hello Bob". So what exactly is going on?

One of the goals of the ASP.NET AJAX Framework is to bridge the gap between the client and the server. In practice, this means that a developer can use a combination of server-side and client-side logic to solve a problem. It does this in a number of ways, including automatically serializing and de-serializing the data on both the client and the server. I won't get into great detail here, as I don't think it's profitable for this discussion. If, however, you'd like a more thorough explanation of what is going on behind the scenes, take a look here. To help you understand what happened in this specific example, we'll take a quick peek behind the scenes using firebug:

firebug

What you are looking at is an automatically generated script file. Most of the file is made up of a JavaScript proxy object which does the work of enabling access to the WebService. The last few lines that I've circled create a definition of a Person object on the client, which is then associated with the server-side Person class. It does this by generating a typed constructor, which basically just means that each Person object that you create will have a __type property, containing the name of the class. Because of that definition, you can both pass a Person to the server as an argument to a WebMethod, or return a Person back to the client, and it will be recognized in both instances. Another cool thing that you'll discover if you dig a bit deeper is that you can also pass collections back and forth. For example, an array or a generic list of Person objects will also be recognized on both the client and server. 

Before I finish, I'll mention one more scenario. If you happen to have a class on the server that you aren't necessarily using in any of your WebMethods, but you want to be able to instantiate and use it on the client, you can add the GenerateScriptType attribute to your WebService. Assuming that I've created another class, called Pet, here is the new WebService:

new webservice

With that attribute set, it is now possible to create a new Pet object in JavaScript, on the client. One thing to remember, as you begin passing objects back and forth between the client and server, is that JavaScript is a dynamic language. The immediately obvious consequence of that fact is that you can add new properties to a JavaScript object at any time. So although the server-side Person may only have Name, Age, and Weight, it is technically possible to add new properties to your client-side Person at any time during program execution. The consequence of this could be lost data. If, for example, you were to add a ShoeSize property to your client object, and then pass the Person as an argument to a WebMethod, there won't be any error. The Person on the server will simply be populated with the Name, Age, and Weight, but the ShoeSize data will be thrown away.

And finally I'll mention something that came up during a conversation I had at Toronto Code Camp on this topic. During the conversation, we were wondering whether or not the generated constructor contains definitions for the properties of the server-side object. I looked into it yesterday and discovered that it does not. In practice, this doesn't actually matter, however. Being a dynamic language, the following two snippets of code in JavaScript produce exactly the same result:

Example 1

function Person() {
this.Age = null;
this.Name = null;
}
var Bob = new Person();
Bob.Name = "Bob";
Bob.Age = 35;

Example 2

function Person() {}
var Bob = new Person();
Bob.Name = "Bob";
Bob.Age = 35;

Basically the only real downside of the constructor not getting pre-populated with the correct properties is that you don't get intellisense for your client-side objects until you begin to assign them properties. Since JavaScript intellisense is a very new thing in Visual Studio, anyway, probably this is a problem I can overlook for the moment. :)



Related posts

Add comment


 

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

July 23. 2008 18:22