Tutorial: Passing objects from Flex 3 to ASP.NET Web Services and back

Post to Twitter

To complete this tutorial you will need a copy of Flex Builder 3 (there is a free trial version available) and Visual Studio 2008 (I used the “Professional” edition) with the .NET Framework 3.5 and IIS 6 or 7. Also you need to have the JSON AS3CoreLib.

First, you need to create a new Flex project in Flex Builder. Give it a project name of “PassingObjects”. Once the Flex Builder designer is loaded you can drag an MX:Panel onto the design surface. Put the Panel somewhere in the middle. Drag a MX:Button onto the Panel and set the label property to “Run” and the ID property to “run_btn”. Finally drag a MX:TextArea onto the Panel above the button. Set it’s VerticalScrollPolicy to “true” and it’s “ID” to “output_txt”.

You should have something like this:

passingobjects1.jpg

Time to setup AS3CoreLib. Make sure you’ve extracted the as3corelib into your “src” working folder for the Flex project, here are the files and directory structure we want to have:

passingobjects0.jpg

Lets move over to Visual Studio 2008 now. Open up Visual Studio (make sure if you are using Vista that you right-click on the Visual Studio icon and use the “Run as administrator” option so Visual Studio has privileges to create a new website in IIS 7. I’m going to assume you have IIS installed and working with ASP.NET 3.5, in my case I’m using Windows Vista with IIS 7 and the .NET Framework 3.5 as my default. Once your Visual Studio is up and running create a new website. Then pick the “ASP.NET Website” option and set the “Location” to “HTTP” with a value of “http://localhost/PassingObjects”.

passingobjects2.jpg
(Click to enlarge)

Once the wizard has finished it’s magic go ahead and remove the Default.aspx webpage (right-click on the file in the Solution Explorer and select “Delete”). Now right-click on the “http://localhost/PassingObjects” in the Solution Explorer and select “Add new item”. From that dialog choose “WebService”.

passingobjects3.jpg
(Click to enlarge)

Time to modify the web service generated code. Make your code look like this:

using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
// Make sure to add this next line!
using System.Web.Script.Services;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
[GenerateScriptType(typeof(MyObject))]
public class WebService : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public MyObject DoSomethingWithMyObject(MyObject obj)
    {
    }
}

Ok, the code is not done yet but lets explain what we did so far. First, we uncommented the line that lets ScriptService do it’s magic -which is essentially making it so scripts like AJAX calls (JavaScript) can talk to this method. In our case it will be Flex instead of a JavaScript AJAX call. After the ScriptService we add GenerateScriptType and tell it to generate a scriptable type of MyObject. Basically we will have a class called MyObject and our web service will do it’s best to turn that class into JSON, hence why we added the ScriptMethod(ResponseFormat = ResponseFormat.Json) over the DoSomethingWithMyObject method call. We want that call to take and argument of the MyObject and pass back that object except we will modify it’s contents.

Obviously now we need to actually create the “MyObject” class. So right-click on the “http://localhost/PassingObjects” in the Solution Explorer and select “Add new item” and pick “Class”. Change the name of the file to “MyObject.cs”. If you get a dialog saying you should place the new class in an “App_Code” folder go ahead and say “Yes”. You should now be in the new empty MyObject class. Here we need to add the following code:

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

[Serializable]
public class MyObject
{
    public String name { get; set; }
    public String favoriteGame { get; set; }
    public String favoriteRockGroup { get; set; }
}

Pretty easy stuff. We just defined three string properties.

Lets finish off that method in the web service. Here is the final code:

using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
// Make sure to add this next line!
using System.Web.Script.Services;


[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
[GenerateScriptType(typeof(MyObject))]
public class WebService : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public MyObject DoSomethingWithMyObject(MyObject obj)
    {
        obj.favoriteGame = "Dungeons and Dragons";
        obj.favoriteRockGroup += " and AC/DC";
        obj.name += "!";
        return obj;
    }
}

We are just going to modify the object a bit and return it to Flex.

Compile this to make sure it works. If it doesn’t work double check the steps and code above.

Now, lets move back to our Flex Builder 3 project.

We need to create a similar MyObject class in ActionScript 3. From the Flex Builder menu select “File -> New -> ActionScript Class”. Give it a name of “MyObject”.

Modify the code to look like our C# MyObject class except in ActionScript syntax:

package
{
	public class MyObject
	{
		public var name:String;
		public var favoriteRockGroup:String;
		public var favoriteGame:String;
	}
}

We are now ready to add the final bits of code. Go back to the “PassingObjects.mxml” page in Flex Builder and click on the “Source” button. Lets go ahead and add the code to call the web service.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
		<mx:Script>
		<![CDATA[
    		import flash.net.*;
    		import com.adobe.serialization.json.JSON;

	        private function CallWebService():void
	        {
	            var loader:URLLoader = new URLLoader();
	            var obj:MyObject = new MyObject();
	            var header:URLRequestHeader = new URLRequestHeader("Content-Type", "application/json");
	            var header2:URLRequestHeader = new URLRequestHeader("pragma", "no-cache");

	            configureListeners(loader);

	            var request:URLRequest = new URLRequest("http://localhost/PassingObjects/WebService.asmx/DoSomethingWithMyObject");
	            request.requestHeaders.push(header);
	            request.requestHeaders.push(header2);
	            request.method = URLRequestMethod.POST;

	            obj.name = "Fred";
	            obj.favoriteGame = "Magic the Gathering";
	            obj.favoriteRockGroup = "Twisted Sister";

	            request.data = '{"obj":' + JSON.encode(obj) + '}';
	            trace("Sending: " + request.data);

	            loader.dataFormat = URLLoaderDataFormat.TEXT;
		    loader.load(request);
	        }

	        private function configureListeners(dispatcher:IEventDispatcher):void
	        {
	            dispatcher.addEventListener(Event.COMPLETE, completeHandler);
	            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
	            dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
	            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
	        }

	        private function completeHandler(event:Event):void
	        {
	            var loader:URLLoader = URLLoader(event.target);
	            output_txt.text = loader.data;

	            var obj:Object = JSON.decode(loader.data);

	            output_txt.text += "\n\nName: " + obj.d.name;
	            output_txt.text += "\nFavorite Game: " + obj.d.favoriteGame;
	            output_txt.text += "\nFavorite Rock Group: " + obj.d.favoriteRockGroup;
	        }

	        private function securityErrorHandler(event:SecurityErrorEvent):void
	        {
	            output_txt.text = "securityErrorHandler: " + event;
	        }

	        private function httpStatusHandler(event:HTTPStatusEvent):void
	        {
	            output_txt.text = "httpStatusHandler: " + event;
	        }

	        private function ioErrorHandler(event:IOErrorEvent):void
	        {
	            output_txt.text = "ioErrorHandler: " + event;
	        }
		]]>
	</mx:Script>
	<mx:Panel width="398" height="296" layout="absolute" title="PassingObjects" horizontalCenter="0" verticalCenter="0">
		<mx:Button x="165" y="224" label="Run" id="run_btn" click="CallWebService();"/>
		<mx:TextArea x="10" y="10" height="206" verticalScrollPolicy="on" width="358" id="output_txt" color="#000000"/>
	</mx:Panel>
</mx:Application>

Lots going on here. I know I could probably have used the MX:WebService call here, but I think doing it the way I did above makes it easier to see whats going on.

The URLLoader class is one of my favorites. It is available in both Flash CS3 and Flex 2/3 (possibly also in prior releases of each product too). The important things in the code is that we hook up the “Run” button to call out to the web service. At that point we pass in two headers, the real important one here is the “application/json” one. Without that header set the ASP.NET Web Service would return XML even though we told it JSON. Then we setup some listeners so when our call returns we can handle any problems or the returning JSON on a successful call. We make use of the POST method and encode our MyObject into JSON:

request.data = '{"obj":' + JSON.encode(obj) + '}';

Since our Web Service takes an agrument of MyObject obj, we need to tell it that the JSON is indeed the argument it’s looking for. Now the Web Service will mess with that object and send it back to us which we catch in the “completeHandler” method. At that point we can decode the incoming JSON and print the objects contents and you should see this:

passingobjects4.jpg
(Click to enlarge)

You can now see the JSON returned as well as our modified object we passed into the Web Service.

ASP.NET does something unusual with JSON it returns in wrapping our object in “d”. This is done because for compatibility with their ASP.NET AJAX extensions I’m told. So keep that in mind when digging your objects out.

Post to Twitter

This entry was posted in ActionScript, ASP.NET, C#, Flex. Bookmark the permalink.

19 Responses to Tutorial: Passing objects from Flex 3 to ASP.NET Web Services and back

  1. Rohit Tailor says:

    Example is good but if it be explained with out JSON than this would be beneficial for most of the FLEX DEVELOPERS

  2. mojgan says:

    hello
    would you help me?
    when i run my application from iis
    there is no data in page
    i use from iis 5- flex 3- asp.net 2- webservices
    what shal i do?
    please help me?

  3. Ruth says:

    Thanks! This was really useful. Most examples don’t really work – this one does and the explanation was very helpful.

  4. César F. Qüeb Montejo says:

    Thank you so much!… really is appreciated this info.

    Regards

  5. Ridha says:

    Great, I love this style…..!!!

  6. woohoo says:

    great tutorial, thank you.

    but, what a shame the spelling is not as good:

    “if your using Vista” should read: “if you’re using Vista”, or even more clear: “if you are using Vista”…

  7. Chad Lung says:

    @woohoo,

    Thanks, updated.

  8. Jason Kitson says:

    Great example. Very difficult to source simple .net webservices interaction examples like this one. One thing I am having trouble with is the JSON sent back from my .net2 application is not being decoded correctly.
    Hence,

    var obj:Object = JSON.decode(loader.data); is not working.

    I am wondering whether the decode method looks for a matching class name in the Flex app?

    I have called my object class “SimpleTest”. The JSON that is sent back refers to a class call MyFlexWS.SimpleTest
    (Note the additional namespace)

    So I am assuming that the decode method is searching for a class definition that corresponds to SimpleTest and cannot find it because of the namespace.

    Is this a assumption or does the decode method not care about class names?

  9. Jason Kitson says:

    Last line is meant to read “Is this a CORRECT assumption…”

  10. Fixis says:

    The tutorial is good, thank you. However I am having a hard time trying to pass a string array from Flex to .net. Does anyone have an idea how can this be done?

  11. Fixis says:

    I used different names, of course it wouldn’t work, sorry for the post. Great tutorial.

  12. Johnny says:

    Look, thanks. This has been the most effective first stop I have seen explaining a simple interaction between iis and flex, in fact its a great deal easier to understand than the tutorials I have been depressing myself with from weborb, the annoying thing is that weborb looks seriously seriously good, and now hopefully ill have a better chance of getting to grips with it, thanks again.

  13. Prabhu says:

    Nice article, but it seems it works only with .Net 3.5 and Flex3. I tried with .Net 2.0 version, I couldn’t succeeded. It would be better if u attach the same as a sample application.

    Anyhow, I added this page in my fav… :) thanks. Worth Reading…

  14. Pingback: Getting Perl and Flex talking via XML | Giant Flying Saucer

  15. Casey Bentz says:

    I am wondering how to debug the web service. I have a much more complicated object that I am attempting to send to the web service and do some manipulation of the object when it gets there. The problem is, that I don’t know how to debug the service.

  16. Thank you for the tutorial.

    I got this working with .Net 4 (using VB.NET) and Flash Builder 4 (using Flex SDK 4.0).

    If anyone wants the whole chabang send me an email and I’ll let you have it.

  17. I dunno how you email from this site. If you need to reach me, you can use the form at our company site by selecting my name in the drop-down list:
    http://www.databyran.nu/default.asp?action=contact

  18. naresh k says:

    this is very useful ineed some help to data is tranfor the flex application to asp.net page and this data saved in the datbase

  19. Dan says:

    Once again Chad is the man.
    Follow the directions, and everything works.
    A nice example to build a framework for .Net->Flex integration.

    Anyone have problems, I have working versions on both flex and .net code. (Which happens to be exactly what is up above in the article).

Comments are closed.