Ehsan Mahpour’s Weblog

ASP.NET

Cross Domain Ajax Calls

by mahpour on Aug.29, 2007, under ASP.NET, HTML/CSS Tips

When Microsoft added the ActiveX XMLHTTP object to Internet Explorer’s implementation of JavaScript, the company planted the seed for the revolution in Web applications known as Asynchronous JavaScript and XML, or AJAX. Today, Firefox, Safari, Opera, and other browsers all support what is now known as XMLHttpRequest, making possible sites such as colr.org, backpackit.com, and maps.google.com. These and other sites feature applications that act and feel like other desktop applications—even though they’re running in a browser.

In AJAX, the JavaScript on the page sends requests to a Web server for data while the user’s viewing and interacting with the page (hence the "asynchronous" part of AJAX). Those requests are HTTP requests just like the one the browser used to retrieve the page in the first place, as well as any images, stylesheets, and so forth. As such, the XMLHttpRequest object can be used to retrieve any kind of data, not just XML. For example, JavaScript can use XMLHttpRequest to retrieve a plain text file from a Web server and display its contents within a form.

The XMLHttpRequest object analyzes the MIME type of the data coming back from the Web server by looking at the Content-type header that precedes the data. If it’s text/plain for example, you can access the text by examining the XMLHttpRequest object’s responseText property. But, if it’s text/xml, the XMLHttpRequest object takes an extra step: It runs an XML parser on the returned document and builds a Document Object Model (DOM) tree in memory representing the document, and makes that available in the responseXML property. You then can use JavaScript’s standard DOM methods to navigate the tree and retrieve elements, attributes, and other text occurring in the tree.

XML is the standard way to interchange data, but it’s often not the best way. Although XML can add structure and metadata to data, it does so in an overly verbose way. XML also has a fairly complex syntax, requiring a non-trivial parser to attack it. In JavaScript, XML must be parsed into a DOM tree to be used. And, once you’ve constructed the DOM tree, you still have to pilot through it to create corresponding JavaScript objects or otherwise use the XML data in your client-side Web application.

Fortunately, there’s a better way.

Welcome to JSON

The JavaScript Object Notation, or JSON, is a lightweight syntax for representing data. JSON’s elegance comes from the fact that it’s a subset of the JavaScript language itself. You’ll see why that’s important later. First, compare the raw syntax of JSON against XML.

Both XML and JSON use structured approaches to mark up data. For example, an address book application might provide a Web service that yields address cards in this XML format:

<?xml version='1.0' encoding='UTF-8'?><card>   <fullname>Sean Kelly</fullname>   <org>SK Consulting</org>   <emailaddrs>      <address type='work'>kelly@seankelly.biz</address>      <address type='home' pref='1'>kelly@seankelly.tv</address>   </emailaddrs>   <telephones>      <tel type='work' pref='1'>+1 214 555 1212</tel>      <tel type='fax'>+1 214 555 1213</tel>      <tel type='mobile'>+1 214 555 1214</tel>   </telephones>   <addresses>      <address type='work' format='us'>1234 Main St         Springfield, TX 78080-1216</address>      <address type='home' format='us'>5678 Main St         Springfield, TX 78080-1316</address>   </addresses>   <urls>      <address type='work'>http://seankelly.biz/</address>      <address type='home'>http://seankelly.tv/</address>   </urls></card>

With JSON, it looks like this:

{   "fullname": "Sean Kelly",   "org": "SK Consulting",   "emailaddrs": [      {"type": "work", "value": "kelly@seankelly.biz"},      {"type": "home", "pref": 1, "value": "kelly@seankelly.tv"}   ],    "telephones": [      {"type": "work", "pref": 1, "value": "+1 214 555 1212"},      {"type": "fax", "value": "+1 214 555 1213"},      {"type": "mobile", "value": "+1 214 555 1214"}   ],   "addresses": [      {"type": "work", "format": "us",       "value": "1234 Main StnSpringfield, TX 78080-1216"},      {"type": "home", "format": "us",       "value": "5678 Main StnSpringfield, TX 78080-1316"}   ],    "urls": [      {"type": "work", "value": "http://seankelly.biz/"},      {"type": "home", "value": "http://seankelly.tv/"}   ]}

As you can see, JSON has structure with nesting of data elements, just as XML does. JSON too is text-based, as XML is. Both use Unicode. JSON is just as readable by humans as XML is. Subjectively, JSON is clearer and has less redundancy. The JSON Web site describes the syntax of JSON rigorously, and yet does so briefly. It really is a simple little language! XML is certainly appropriate for marking up documents, but JSON is ideal for data interchange. Each instance of a JSON document describes one object with nested objects, arrays, strings, numbers, boolean values, or null values.

In these address card examples, the JSON version is lighter weight, taking 682 bytes of space, whereas the XML version requires 744. That’s not a spectacular savings, of course. The real benefits come in the parsing.

XML Versus JSON: the Smackdown!

By using the XMLHttpRequest object, you can retrieve both XML and JSON files from within your AJAX-based application. Typically, your interaction will go something like this:

var req = new XMLHttpRequest();req.open("GET", "http://localhost/addr?cardID=32", /*async*/true);req.onreadystatechange = myHandler;req.send(/*no params*/null);

As the Web server replies, the handler function you passed in (myHandler in this example) is called repeatedly, affording you an opportunity to abort the transaction early, update a progress bar, and so forth. Frequently, you only take action when the Web request is complete; at that time, you use the returned data.

To handle the XML version of your address card, the code for myHandler might look something like this:

function myHandler() {   if (req.readyState == 4 /*complete*/) {       // Update address field in a form with first street address       var addrField   = document.getElementById('addr');       var root        = req.responseXML;       var addrsElem   = root.getElementsByTagName('addresses')[0];       var firstAddr   = addrsElem.getElementsByTagName('address')[0];       var addrText    = fistAddr.firstChild;       var addrValue   = addrText.nodeValue;       addrField.value = addrValue;   }}

Notice that you didn’t have to parse the XML document; the XMLHttpRequest object did that automatically and made the parsed DOM tree available in the responseXML property. By using that property, you call the getElementsByTagName method to find the addresses part of the document, and you use the first one (of only one) found. Then, you call getElementsByTagName again this time on that addresses element to find the first address element, and again use the first one found. Then, you get the first DOM child of that element, which is a text node, and get the node’s value, which is the street address you want. Finally, you can display it in the form field.

That’s a lot of work! Now, let’s try it with JSON:

function myHandler() {   if (req.readyState == 4 /*complete*/) {       var addrField = document.getElementById('addr');       var card = eval('(' + req.responseText + ')');       addrField.value = card.addresses[0].value;   }}

The first thing you need to do is manually parse the JSON response. However, because JSON is a subset of JavaScript, you can use JavaScript’s own compiler to do just that by calling eval. Parsing JSON is a one-liner! Moreover, navigating an object synthesized from JSON is identical to navigating any JavaScript object. It’s far easier than navigating through the DOM tree. For example:

  • card.addresses[0].value is the first street address, "1234 Main Stb &"
  • card.addresses[0].type is the type of the address, "work"
  • card.addresses[1] is an object which is the home address
  • card.fullname is the name on the card, "Sean Kelly"

If you’re watching closely, you might’ve noticed that the XML version at least states up front what object is contained in the document with the root document element, card. This is absent in the JSON version. Why? Presumably, if you’re developing JavaScript that accesses a Web service, you already know what you’re going to get back. However, you can include such a nicety in JSON:

{"card": {"fullname": ...}}

By using this technique, your JSON files always start with an object with a single named property that identifies the "kind" of the object.

Leave a Comment more...

Setup a source versioning software on your windows server for FREE!

by mahpour on Apr.24, 2007, under ASP.NET, Uncategorized

Subversion sounds pretty cool. It’s a mature, powerful revision-control system that acts a lot like CVS, adds support for atomic commits and real renames, just won the Jolt award, and is free. What more can you ask for?

I’ve been intending to install Subversion for quite a while, but I kept putting it off, because it looked like a daunting task. But when I actually decided to go do it, it took me all of an hour and a half to get it installed and working. If somebody had just written down what I needed to do to set up Subversion on Windows, with a real server running as a real Windows service, then it probably would’ve only taken me ten minutes, and I would’ve done it weeks ago.

Here, then, is the Mere-Moments Guide to installing a Subversion server on Windows. (It may look a bit intimidating, but really, it’s not.)

Some quick notes on the Guide:

  • These instructions assume you’re using Windows 2000 or XP. (You’d better be; the Subversion server won’t run on Win9x.)
  • If you want to know more about Subversion than just how to install it, check out the free O’Reilly Subversion book online and the not-free Pragmatic Version Control using Subversion.
  • For Subversion to do you much good, you’ll have to add a new "project" (essentially a directory) to your repository, to put files in. In these instructions, I’m assuming that your new project will be called monkey (because mine was).
  • Feel free to skip steps and to play around; you’ll learn more that way, because things won’t work right and you’ll have to figure out why.

And now, on to the Guide.

  1. Download everything
    1. Go to http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91 and download the most recent svn-x.y.z-setup.exe. At the time of this writing, the latest version was svn-1.2.0-setup.exe.
    2. Go to http://dark.clansoft.dk/~mbn/svnservice/ and download SVNService.zip.
    3. Go to http://tortoisesvn.tigris.org/download.html and download the most recent installer. At the time of this writing, the latest version was TortoiseSVN-1.1.7-UNICODE_svn-1.1.4.msi. (It doesn’t have to be the exact same version as the svn installer you got in step 1. See the compatibility chart.)
  2. Install the server and the command-line client
    1. Run svn-x.y.z-setup.exe and let it install stuff.
    2. Go to Control Panel > System, go to the Advanced tab, and click the "Environment Variables" button at the bottom. Click the "New" button (either one, but if you’re undecided, use the one under "System variables"), set "variable name" to SVN_EDITOR, and "variable value" to the path and filename of a text editor of your choice (e.g., C:\Windows\Notepad.exe). OK all the way out.
  3. Create a repository and configure access
    1. Create a new directory somewhere out of the way; this is where your repository will live, but you’ll almost never actually open the files directly. I made a directory called svn_repos directly under my C:\Documents and Settings, just so it’d be out of the way.
    2. Open a command prompt and type: svnadmin create "C:\Documents and Settings\svn_repos"
    3. In Windows Explorer, browse to the C:\Documents and Settings\svn_repos\conf directory (which svnadmin just created for you), and edit a couple of config files:
      1. Open the svnserve.conf file in a text editor, and uncomment the [general], anon-access = read, auth-access = write, and password-db = passwd lines. Save.
      2. Open the passwd file in a text editor, uncomment the [users] line, and add the username and password you want to use when connecting to your subversion server. Save.
  4. Start the server manually, and create a project
    1. In your command window, type: svnserve –daemon –root "C:\Documents and Settings\svn_repos"
    2. Open a second command window, and type svn mkdir svn://localhost/monkey
    3. You’ll see the text editor you specified in step II.2, with some text already in it. Type a comment, like "Created the monkey project", at the beginning of the file (before the line starting with "–"). Save the file and close the editor.
    4. If your Subversion login is the same as your Windows login, then type your password (the one you put in the passwd file) at the prompt, and hit Enter. If your Subversion login is different from your Windows login, then just hit ENTER at the password prompt, and Subversion will then ask for both your login and your password.
    5. Subversion should tell you that it "Committed revision 1." Congratulations! You just checked a change into Subversion. Throw yourself a party. (Yes, creating a directory is a revisioned change — you can go back and get the repository as of a time before that directory existed. This is novel stuff for folks like me who still use VSS at work.)
    6. It’s conventional to have /trunk, /branches, and /tags subdirectories for each project (your code goes into trunk, and the others are where you put, well, branches and tags). Go ahead and type svn mkdir svn://localhost/monkey/trunk (and notice that, after you enter a checkin comment, it doesn’t prompt you for your password again — it’s smart like that).
  5. Start the server for real
    1. Go back to the command window that’s running svnserve. Hit Ctrl+C to stop it.
    2. Open the SVNService.zip that you downloaded earlier. Extract SVNService.exe into your Subversion bin directory (Program Files\Subversion\bin). Yes, it’s important that you put it in this directory; it has to be in the same place as svnserve.exe from the Subversion distribution.
    3. In a command prompt, type svnservice -install –daemon –root "C:\Documents and Settings\svn_repos"
    4. Go to Control Panel > Administrative Tools > Services, double-click the SVNService service, and change its startup type from "Manual" to "Automatic". Now Subversion will start every time you start Windows.
    5. Start the SVNService service (by selecting it in the Services list, and clicking the "play" toolbar button).
    6. Go back to a command prompt, and type svn ls svn://localhost/
      This will list all the files in the root of the repository. If all is well and you’ve got a real Subversion server running now, you should see: monkey/
  6. Install TortoiseSVN
    Sure, you can get by with a command-line client, but TortoiseSVN is cool — it integrates Subversion into Windows Explorer. You get little overlay icons showing the status of each file (in sync, needs to be checked in, not yet in the repository, etc.), and you can do pretty much everything you need by right-clicking on files and folders.

    1. Run the TortoiseSVN installer you got back in part I.
    2. Create a monkey directory somewhere on your hard drive. Right-click somewhere in that folder and select "SVN Checkout…" Type svn://localhost/monkey/trunk/ for the repository URL and click OK.
    3. Create a file in that directory, any file. Right-click the file and select TortoiseSVN > Add. Notice the little plus-sign icon that appears.
      The file hasn’t actually been checked in yet — Subversion’s commits are both batched and atomic, so this new file, together with any other new files you added, any files you changed, any files you deleted, any files you renamed, any directories you added or deleted or renamed, will all show up on the server all at once, as a single revision and a single checkin, the next time you right-click and select "SVN Commit".
  7. Make it run on the network
    Are you kidding? You’re already networked. Go to another computer on your LAN, install TortoiseSVN, and do an "SVN Checkout…". When you specify the repository URL, use the same URL you did before, but replace "localhost" with the actual name of the computer that’s running the Subversion service (so in my case, the repository URL is svn://marsupial/monkey/trunk/ — nice little menagerie, there).

And there ya go — Subversion up and running on Windows, in mere moments or less.

Corrections, questions, etc. on this document are, as always, welcome; just speak up in the comments. Now go forth and control your revisions.

2 Comments more...

A quick glance at Microsoft Enterprise Library 2.0 - Logging Unhandled Exceptions

by mahpour on Apr.24, 2007, under ASP.NET

Let’s use the Enterprise Library 2.0 Logging Application Block in an ASP.NET 2.0 Website using the most simplistic, yet very important case of logging unhandled exceptions. If you log nothing else in your ASP.NET websites, make sure you log unhandled exceptions so that you have some idea of the health of your application.  Enterprise Library 2.0 can email you the exception if you want, but I am going to keep things real simple and just have the exceptions logged to a file on the webserver.

 

Enterprise Library Configuration Tool

Once I create my website in Visual Studio 2005, I immediately open up the Enterprise Library Configuration Tool and use it to open the existing web.config file.  Using only the tool, I then add the logging application block configuration section to web.config, remove all the defaults, and replace them with a simple FlatFile TraceListener that catches all events as shown below:

 

 

The Logging Application Block has a Special Source, called All Events.  Hooking a TraceListener to this event guarantees you will receive all events not being filtered.  Since we have no filters, we get all events.  These events get logged to the FlatFile TraceListener, which points to a log file at the root of my website, called trace.log ( default name ).

 

Catching and Logging Unhandled ASP.NET Exceptions

To catch unhandled exceptions in ASP.NET 2.0, I need to do a couple of things.

First, I need to reference Microsoft.Practices.EnterpriseLibrary.Logging in my website.  When you reference this library, it will also pull over a couple of other assemblies, Common and ObjectBuilder, that it depends upon.

Second, I need to add a Global Application File ( Global.asax ) to the website and enter the following code into Application_Error:

 

<%@ Application Language="C#" %><%@ Import Namespace="Microsoft.Practices.                       EnterpriseLibrary.Logging" %>

<script runat="server">

    void Application_Error(object sender, EventArgs e)     {        Exception ex = Server.GetLastError().GetBaseException();

        string message = ex.Message +                         "\nSOURCE: " + ex.Source +                        "\nFORM: " + Request.Form.ToString() +                         "\nQUERYSTRING: " +                            Request.QueryString.ToString() +                        "\nTARGETSITE: " + ex.TargetSite +                        "\nSTACKTRACE: " + ex.StackTrace;

        Logger.Write(message);    }

</script>

 

Logger is the name of the facade in the Logging Application Block to log messages.  I grab the unhandled exception and send it out to be logged.  The application doesn’t know and doesn’t care where; it is oblivious as to the actual logging strategy.

 

Creating An Unhandled Exception

Let’s open up Default.aspx.cs file and make it throw an exception:

 

public partial class _Default : System.Web.UI.Page {    protected void Page_Load(object sender, EventArgs e)    {        int error = Int32.Parse("bbbbb");    }}

 

The above with throw a System.FormatException error which will be logged in the trace.log file when running the application:

 

Timestamp: 2/15/2006 9:23:30 PM
Message: Input string was not in a correct format…<Stack Trace>

 

Conclusion

In about 15 minutes, you can successfully log unhandled exceptions in your ASP.NET 2.0 websites using Enterprise Library 2.0 Logging Application Block.

 

Source:  David Hayden ( .NET Developer )

Leave a Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...