Tutorial: Talking to WCF with Flex 3 via JSON or XML

Post to Twitter

Here is a simple tutorial to show you how you can get WCF (hosted in ASP.NET) talking to Flex 3. I used Visual Studio 2008 Pro, IIS 7 and Flex Builder 3 (beta 3). I did my initial inspection of the data moving back and forth with Fiddler2 and Firebug.

Let start with the C# WCF code. First you will need to open Visual Studio 2008 and select “File -> New Website”. Then pick “ASP.NET Website” and for the “location” select “HTTP” and point it to your local IIS. In my case I picked “http://localhost/HelloServices”. Then hit the “Ok” button. Also, if your doing this in Windows Vista then you will need to start Visual Studio in Administrator mode (right-click on the Visual Studio 2008 icon and pick the “Run as Administrator” option from the menu).

Once the project has been created right-click on the new website from the Solution Explorer and select “Add New Item” and select “AJAX-enabled WCF Service”. Call the new file “Greeting.svc”. Delete out the “DoWork()” method from the generated code. Then add a namespace to the file and call it “HelloServices”. Also make sure to fill in the namespace for the “ServiceContract” attribute with “HelloServices” as well. Now we will add a simple method:

using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;

namespace HelloServices
{

    [ServiceContract(Namespace = "HelloServices")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Greeting
    {
        // Add [WebGet] attribute to use HTTP GET
        [OperationContract]
        public String SayHello(String name)
        {
            return "Hello: " + name;
        }

        // Add more operations here and mark them with [OperationContract]
    }
}

Lets go ahead and test this out with the Default.aspx file before we make the Flex project.

Move over to the “Default.aspx” file and go into design mode. From the toolbox select the “AJAX Extensions” and drag over the “Script Manager”. Then from the “HTML” section drag over an “Input (Button)” and drop it on the page. Double click that new input button and it will generate some JavaScript for us. Next, click on the Script Manager that we dragged over already and go into it’s properties. Select the “Services” property and you should get a button with “…”. Click on that button to open up the “ServiceReference Collection Editor”. Press the “Add” button and in the “Path” property enter “Greeting.svc”. Lets add the JavaScript now, your page should look like this:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
<script language="javascript" type="text/javascript">
// <!CDATA[

    function Button1_onclick()
    {
        var svc = new HelloServices.Greeting();
        svc.SayHello("Programmer", onSuccess, null, null);
    }

    function onSuccess(data)
    {
        alert(data);
    }

// ]]>
</script>
</head>
<body>
    <form id="form1" runat="server">
    <div>

        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference Path="Greeting.svc" />
            </Services>
        </asp:ScriptManager>

    </div>
    </form>
    <p>
        <input id="Button1" type="button" value="button" onclick="return Button1_onclick()" /></p>
</body>
</html>

Now a couple important things. Remember when we added the namespace “HelloServices”. We now need to make sure the web.config file and the Greeting.svc file both reflect that. Your Greeting.svc file should look like this:

<%@ ServiceHost Language="C#" Debug="true" Service="HelloServices.Greeting" CodeBehind="~/App_Code/Greeting.cs" %>

The web.config section we are concerned about is the “system.serviceModel”. Yours should look like this (its probably near the bottom of the web.config file):

	<system.serviceModel>
		<behaviors>
			<endpointBehaviors>
				<behavior name="GreetingAspNetAjaxBehavior">
					<enableWebScript/>
				</behavior>
			</endpointBehaviors>
		</behaviors>
		<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
		<services>
			<service name="HelloServices.Greeting">
				<endpoint address="" behaviorConfiguration="GreetingAspNetAjaxBehavior" binding="webHttpBinding" contract="HelloServices.Greeting"/>
			</service>
		</services>
	</system.serviceModel>

Go ahead and run the project. When the Default.aspx page loads click on the button. You should see something like this:

wcf_result.jpg

Assuming that worked for you we can continue onto the Flex part of this tutorial. Open Flex Builder 3 and create a new “Flex Project” and call it “TalkToWCF”. We won’t add any GUI to this just to keep it simple. Make your MXML file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="URLRequestExample();" layout="absolute">

	<mx:Script>
		<![CDATA[
    		import flash.events.*;
    		import flash.net.*;

	        private function URLRequestExample():void
	        {
	            var loader:URLLoader = new URLLoader();
	            var header:URLRequestHeader = new URLRequestHeader("Content-Type", "application/json");

	            configureListeners(loader);

	            var request:URLRequest = new URLRequest("http://localhost/HelloServices/Greeting.svc/SayHello");
	            request.method = URLRequestMethod.POST;
	            request.requestHeaders.push(header);
	            request.data = '{"name":"Programmer"}';

	            try
	            {
	                loader.load(request);
	                trace("Request sent");
	            }
	            catch (error:Error)
	            {
	                trace("Unable to load requested document.");
	            }
	        }

	        private function configureListeners(dispatcher:IEventDispatcher):void
	        {
	            dispatcher.addEventListener(Event.COMPLETE, completeHandler);
	            dispatcher.addEventListener(Event.OPEN, openHandler);
	            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
	            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);
	            trace("completeHandler: " + loader.data);
	        }

	        private function openHandler(event:Event):void
	        {
	            trace("openHandler: " + event);
	        }

	        private function progressHandler(event:ProgressEvent):void
	        {
	            trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
	        }

	        private function securityErrorHandler(event:SecurityErrorEvent):void
	        {
	            trace("securityErrorHandler: " + event);
	        }

	        private function httpStatusHandler(event:HTTPStatusEvent):void
	        {
	            trace("httpStatusHandler: " + event);
	        }

	        private function ioErrorHandler(event:IOErrorEvent):void
	        {
	            trace("ioErrorHandler: " + event);
	        }
		]]>
	</mx:Script>

</mx:Application>

Run the Flex program in debug mode so you will see the trace statements since that is where the output is going. Hopefully you see this in the output:

flex_wcf.jpg

Down at the bottom is the JSON WCF returned to us – click on the image above if its too small to read.

Obviously a person can take this pretty far if you want to. The first thing would be to use the ActionScript CoreLib and parse the JSON coming back as well as encode the JSON you want to sent to WCF.

You can also have WCF send back XML rather than JSON. To do this you simply change your WCF method into this:

        [OperationContract]
        [WebInvoke(ResponseFormat = WebMessageFormat.Xml)]
        public String SayHello(String name)
        {
            return "Hello: " + name;
        }

The result would be this:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hello: Programmer</string>

Post to Twitter

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

19 Responses to Tutorial: Talking to WCF with Flex 3 via JSON or XML

  1. Pingback: Will’s Blog - LINQ to SQL, WCF, JSON and Flex. Oh My.

  2. infocyde says:

    Thanks for posting. There are a lot of dated WCF post out there, this is what I needed. Gracie.

  3. Ayub Patel says:

    I keep getting this error

    Request sent
    openHandler: [Event type="open" bubbles=false cancelable=false eventPhase=2]
    httpStatusHandler: [HTTPStatusEvent type="httpStatus" bubbles=false cancelable=false eventPhase=2 status=415]
    ioErrorHandler: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Stream Error. URL: I am taking this off for security reason the url"]

  4. Ayub Patel says:

    Fiddler gives me details of error as

    HTTP/1.1 400 Bad Request
    Date: Wed, 04 Feb 2009 22:50:02 GMT
    Server: Microsoft-IIS/6.0
    X-Powered-By: ASP.NET
    X-AspNet-Version: 2.0.50727
    Cache-Control: private
    Content-Length: 0

  5. Chad Lung says:

    @Ayub,

    I don’t think you have given enough information to troubleshoot this.

    Chad

  6. Jeff says:

    everytime I try and create this, it keeps telling me that HelloServices is undefined. I am using asp.net 3.5 with visual studio 2008. Can you send me this solution? I think there is a variable being cut off due to the size of the windows on here.

    Thanks!

  7. AJ says:

    The example is not working for me, may be I am doing something wrong.

    Whenever I call http://localhost/HelloServices/Greeting.svc/SayHello from the browser, it says:

    Endpoint not found.

    Any clues what can be wrong?

  8. AJ says:

    Sorry, it was my mistake… I changed SayHello method name…
    Thanks for this excellent resource!

  9. AJ says:

    I have gone back to using .Net 2.0 webservices for now… There is no straight forward way for getting SOAP / Fault Excepetions on the Flex Client :( Any information on it will be helpful!

  10. Larry says:

    I am considering using WCF instead of Web Services and asmx to load into Flex. Can you tell me if it can handle large amounts of data?

  11. Chad Lung says:

    @Larry,

    Depends on how large the data. Typically though WCF won’t have a problem within reason.

    Chad

  12. Tom says:

    hello has anybody applied any WCF security to this example? HTTP based

  13. saha says:

    How do i invoke a method from flex when the method in the WCF service takes a list

    [OperationContract]
    [WebInvoke(ResponseFormat = WebMessageFormat.Json)]
    List GetPeoplesJSON(List locations);

  14. saha says:

    how can we call a .NET WCF method webHTTPBinding which accepts a List from Flex? Thid method also returns List. Flex does it support List? or do we need to conert the WCF service method to Array and then call it in Flex?

  15. saha says:

    I just followed this tutorial, for calling the WCF method which takes and returns List, I gave the request as

    request.data = ‘{“name of the List parameter used in WCF method”:”array converted from the string accepted from user”}’;

    I am accepting a String seperated by commas from user and use the split method based on comma and convert the elements to an array

    Error is
    Request sent{“locations”:”USA,Canada”}
    openHandler: [Event type="open" bubbles=false cancelable=false eventPhase=2]
    httpStatusHandler: [HTTPStatusEvent type="httpStatus" bubbles=false cancelable=false eventPhase=2 status=500]
    ioErrorHandler: [IOErrorEvent type=”ioError” bubbles=false cancelable=false eventPhase=2 text=”Error #2032: Stream Error. URL:

    Please help me with this error, breaking my head from 1 week

  16. Anonymous says:

    Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: http://dev1/RESTService/Service.svc/GetPeoplesJSON
    at WebserviceExample/URLListRequestExample()[C:\Documents and Settings\con\My Documents\Flex Builder 3\WebserviceExample\src\WebserviceExample.mxml:95]
    at WebserviceExample/__myListJSON_click()[C:\Documents and Settings\con\My Documents\Flex Builder 3\WebserviceExample\src\WebserviceExample.mxml:282]

    What is the reason for this error, not able to find anywhere

  17. saha says:

    Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: http://dev1/RESTService/Service.svc/GetPeoplesJSON
    at WebserviceExample/URLListRequestExample()[C:\Documents and Settings\con\My Documents\Flex Builder 3\WebserviceExample\src\WebserviceExample.mxml:95]
    at WebserviceExample/__myListJSON_click()[C:\Documents and Settings\con\My Documents\Flex Builder 3\WebserviceExample\src\WebserviceExample.mxml:282]

    What is the reason for this error, not able to find anywhere

  18. Pingback: flex to c# « Flex Developers Blog

  19. Dan says:

    FYI for the people getting the 2032 errors (Ayub, saya)
    LOOK and understand before doing!
    The reason everything works as explained above (exactly without a change to anything) is because of browser security and such.
    If you follow the instructions of setting up the web service in localhost, and using the MXML using localhost, everything works just fine.
    When you say to yourself, I don’t need localhost, but a named instance of my box IP or something else, you are no longer doing the same action.
    So when you are running your flex application if you set to run your flex app from the same domain name, http://dev1/ (from above) and your flex app is running anywhere but http://dev1/… you will get a 2032 error unless you have then properly configured cross domain communication in you box, or the boxes/servers you will be accessing.
    Jeff: Are you sure that you did not choose ScriptReference for the AjaxService instead of ServiceReference. I did the same exact thing, and had the same problem you had. Once I fixed this, things went golden.

    Follow the directions above, step by step, and everything will work 100%. It worked for me just fine. Now I have a nice framework to but some JSON services for testing my Flex->.Net->Flex communications.

    Thanks Chad for the great tutorial.

Comments are closed.