go to edeveloper | view example | download example

Building a Newsfeed Application with Flash MX and ASP.NET
This news feed uses the WebClient() class that is built into Microsoft's .net framework to download the contents of an external file. The contents can then be parsed and displayed locally. Here is the code we are using:
	<%@ Import NameSpace="System" %>
	<%@ Import NameSpace="System.Net" %>
	<%@ Import NameSpace="System.IO" %>
	<%@ Import NameSpace="System.Text.RegularExpressions" %>
	<script language="C#" runat="server">
		
		string _path = "http://www.macromedia.com/desdev/resources/macromedia_resources.xml";
	
		public void Page_Load(Object sender, EventArgs e) { 
			getData(_path);
		}
	
		protected void getData(string url){
			string _url = "";
			string _urlAry = "";
			string _desc = "";
			string _descAry = "";
			string _titleAry = "";
			
			WebClient request = new WebClient();
			Stream s = request.OpenRead(url);
			StreamReader sr = new StreamReader(s);
			Regex myRegex = new Regex(@"(<url>.*</url>)|(<title>.*</title>)");
	
			MatchCollection mc = myRegex.Matches(sr.ReadToEnd());
					
			foreach (Match m in mc){
				if (m.Value.IndexOf("url") > 0){
					_url = m.Value;
					_url = _url.Replace("<url>","");
					_url = _url.Replace("</url>","");
					_urlAry += _url + "|";
				} else {
					_desc = m.Value;
					_desc = _desc.Replace("<title>","");
					_desc = _desc.Replace("</title>","");
					_descAry += _desc + "|";
				}
			}
	
			_descAry = _descAry.Substring(0,_descAry.Length-1);
			_urlAry = _urlAry.Substring(0,_urlAry.Length-1);
			Response.Write ("theUrls="+Server.UrlEncode(_urlAry)+"%26amp;theTitles="+Server.UrlEncode(_descAry));
		}
	</script>
Now let's break this up into sections and take a closer look at what is going on:

	<%@ Import NameSpace="System" %>
	<%@ Import NameSpace="System.Net" %>
	<%@ Import NameSpace="System.IO" %>
	<%@ Import NameSpace="System.Text.RegularExpressions" %>
The language to use is C# and the location to run this script is on the server. When declaring variables in C#, you must specify a data type. The variable "_path" is declared as a string. The function Page_Load will run whatever functions are inside it when the page loads.
	<script language="C#" runat="server">
	
		string _path = "http://www.macromedia.com/desdev/resources/macromedia_resources.xml";
	
		public void Page_Load(Object sender, EventArgs e) { 
			getData(_path);		
		}
This is the getData() function and inside it is the variable being passed in (url). First, we initialize the variables being used in the function. Next we create a new instance of the WebClient class and use the stream variable "s" to hold the data that is contained in the OpenRead() method of the WebClient class. The StreamReader reads the Stream variable "s".

myRegex is a regular expression pattern that is being used to look for the fields we want in the xml data now stored in the StreamReader. This is a simple pattern that is looking for the opening and closing "<url>" and "<title>" tags and the string contents inbetween. Next, we use the MatchCollection to find any matches inside the StreamReader using passing through the file using the ReadToEnd() method of the StreamReader.
	protected void getData(string url){
		string _url = "";
		string _urlAry = "";
		string _desc = "";
		string _descAry = "";
		string _titleAry = "";
		
		WebClient request = new WebClient();
		Stream s = request.OpenRead(url);
		StreamReader sr = new StreamReader(s);
	
		Regex myRegex = new Regex(@"(<url>.*</url>)|(<title>.*</title>)");
	
		MatchCollection mc = myRegex.Matches(sr.ReadToEnd());
Now that we have all the matches stored in the MatchCollection, we can loop through check to see whether or not it's an "<url>" or a "<title>" tag. No matter which it ends up being, we transfer the Match value to the variable "_url" or "_title". Then the Replace() function will take each instance of either tag and replace it with nothing. That variable is the concatenated to the array variable and seperated with the straight piping ("|"). This will have the array looking something like this: _urlAry = "value1|value2|value3|"

Since we are left with an extra piping after the last variable has be added to the array, using the Substring() function will remove it. There are two arguments to the Substring function. Where to start and where to end. _descAry.Substring(0,_descAry.Length -1) states the we want the Substring to start at the first character in the string and go the whole length of the string but minus one character. After that has been done for both arrays, the only thing left is to write the variables being sent to Flash (theUrls and theTitles), and give them their values. To ensure that the values don't contain any characters that Flash or the browser might get confused with, the values are wrapped in the server method - Server.UrlEncode();
		foreach (Match m in mc){
			if (m.Value.IndexOf("url") > 0){
				_url = m.Value;
				_url = _url.Replace("<url>","");
				_url = _url.Replace("</url>","");
				_urlAry += _url + "|";
			} else {
				_desc = m.Value;
				_desc = _desc.Replace("<title>","");
				_desc = _desc.Replace("</title>","");
				_descAry += _desc + "|";
			}
		}
	
			_descAry = _descAry.Substring(0,_descAry.Length-1);
			_urlAry = _urlAry.Substring(0,_urlAry.Length-1);
			Response.Write ("theUrls="+Server.UrlEncode(_urlAry)+"%26amp;theTitles="+Server.UrlEncode(_descAry));
		}
	</script>
Now let's take a look at what is happening on the Flash side: The Flash part of this application is done entirely in ActionScript. That includes the display, text styles and backgrounds.
Here we set the global styles for text formatting. No font sizes are being set here. Font sizes will be set on each text box. That way, the other style attributes can be reused.
	function set_gStyles(){
		tStyle = new TextFormat();
		tStyle.font = "verdana";
		tStyle.color = parseInt("ffffff",16);
		tStyle.leftMargin = 5;
	}
This function creates a textfield to relay the status of communicating with the server. The text size is set to 10 and uses the global text styles.
	function chk_server_conn(){
		_root.createTextField("item_text",0,0,(_root["newsitem_text"]._y)+23,300,16);
		tStyle.size = 10;
		_root["item_text"].selectable = false;
		_root["item_text"].text = "Checking Server Connection";
		_root["item_text"].setTextFormat(tStyle);
	}
This function sets the textfield message to read that a connection could not be established with the exteranl file.
	function showErrMsg(){
		tStyle.size = 10;
		_root["item_text"].text = "Connection Failed";
		_root["item_text"].setTextFormat(tStyle);
	}
This function makes the header box that reads "Macromedia News". First we create an empty movieclip, give it an instance name of "headerbg" and set the depth to -1. Then the box has a color fill of "#284E75" and a dark gray, half pixel stroke. The move to function places the starting x and y coordinates for the box on the stage and the lineTo() function draws the box. The endFill() function closes everthing up. Next, we create a textfield named header and set it's attributes.
	function make_header(){
		_root.createEmptyMovieClip ("headerbg", -1);
			with (_root["headerbg"]){
				beginFill (0x284E75);
				lineStyle (.5, 0x333333, 100);
				moveTo (0, 0);
				lineTo (0, 23);
				lineTo (450, 23);
				lineTo (450, 0);
				endFill();
			}
			
		_root["headerbg"].createTextField("header",110,0,0,300,16);
		_root["headerbg"]["header"].text = "Macromedia News";
		_root["headerbg"]["header"].type = "static";
		_root["headerbg"]["header"].selectable = false;
		_root["headerbg"]["header"].autoSize = "left";
		tStyle.size = 14;
		_root["headerbg"]["header"].setTextFormat(tStyle);
	}
The same principals as above but used to make the box that will contain the news item_text.
	function make_newsitem(){
		_root.createEmptyMovieClip ("news_item", -20);
			with (_root["news_item"]){
				moveTo (0, 10);
				beginFill (0x336699);
				moveTo (0, 23);
				lineTo (0, 40);
				lineTo (450, 40);
				lineTo (450, 23);
				endFill();
			}
	}
This is the function that duplicates the "news_item" clip for each news item. The variables being passed in from the getNews() function are: tAry = myTitleAry and uAry = myUrlAry. These arrays come from the get_news() function. The for()loop loops thru the length of the url array and duplicates the "news_item" clip and gives each a new instance name and depth. Then the y position is set for the new clip using the position of the original clip and the height of the "news_item" clip multiplied by the number of clip produces so far (i). Next, create a new textfield instance that sits on top of the new "news_item" clip. Set the y position of the textfield equal to that of the new "news_item" clip. The "theUrl" variable is equal to the current index value of the uAry array and the "item_index" variable is equal to the current value of i. Now we can set attributes for the current instance of the textfield. Autosizing will extend the textfield to be atleast as long as the text held within. Set the textfield text value equal to the current index value of the tAry array. Last, we set the global text size and set the global text styles. You may be wondering why i have two incrementing variables in my loop (i and j). i is used for getting the array indexes, clip depths and keeping count in the loop. The variable "j" only has one function - to start the textfield depth above the movieclips. since "i" starts at zero, the first textfield's properties would not be accessable since anything multiplied by 0 is still just 0 and to make sure that there was no conflict with clip depths, we multiply j * 10.
	function makeList(tAry,uAry){
		for (var i=0,j=1;i<uAry.length;i++,j++){
			duplicateMovieClip(_root["news_item"],"news_item"+i,i);
			_root["news_item"+i]._y = (_root["news_item"]._y + ((_root["news_item"]._height-1) * i));
			_root.createTextField("item_text"+i,j*10,0,(_root["news_item"+i]._y)+24,300,14);
			this["news_item"+i].theUrl=uAry[i];
			this["news_item"+i].item_index = i;
			this["item_text"+i].selectable = false;
			this["item_text"+i].autoSize = "left";			
			this["item_text"+i].text=tAry[i];
			tStyle.size = 10;
			this["item_text"+i].setTextFormat(tStyle);
These functions handle the movieclip instance events. "myBg" sets the news_item instance background color using the color object when it is rolled over. Another instance of the color object is used to change the font color when it is rolled over. To get the path to the "item_text" instance that we want to reference, the variable "item_index" is concatenated to the instance name - _root["item_text"].
			this["news_item"+i].onRollOver = function(myColor){
				var myBg = new Color(this);
				myBg.setRGB(parseInt("aaaaaa",16));
				var myFontColor = new Color(_root["item_text"+this.item_index]);
				myFontColor.setRGB(parseInt("333333",16));	
			}
These functions do the same as above but change the colors back when the mouse rolls off the "news_item" movieclip.
			this["news_item"+i].onRollOut = function(){
				var myBg = new Color(this);
				myBg.setRGB(parseInt("336699",16));
				var myFontColor = new Color(_root["item_text"+this.item_index]);
				myFontColor.setRGB(parseInt("ffffff",16));	
			}
			
			this["news_item"+i].onRelease = function(){
				getURL(this.theUrl,"_blank");
			}			
		}		
	}
Here is the function that gets the variables/values from getNews.aspx. "ret"(short for return) is the new instance of LoadVars(). If the function gets a return value from the server (success), then use the split() function on the values and index them into two arrays (myUrlAry and myTitleAry). These values are then used in the makeList() function. If the function does not receive a return value then call the showErrMsg() function.
	function get_news(){
		ret = new LoadVars();
		ret.onLoad = function(success){	
			if(success){
				ret.myUrlAry = ret.theUrls.split('|');
				ret.myTitleAry = ret.theTitles.split('|');
				
				makeList(ret.myTitleAry,ret.myUrlAry);
			} else {
				showErrMsg();
			}
		}
		
		// load the values from "getNews.aspx"
		ret.load("getNews.aspx");
	}
Here is the function that loads the other primary functions
	function init(){
		set_gStyles();
		chk_server_conn();
		make_newsitem();
		make_header();
		get_news();
	}
call the function above
	init();
That's it!! Good Luck!!