.NET Blog

Tony Cavaliere

 
My Favourite Albums
  And the Grappa wins.
E-mail me Send mail
Add to Technorati Favorites AddThis Feed Button

Subscribe to Cynot Why Not


Recent posts

Disclaimer

Hey unlike other bloggers I stand by what I say but just in case. The opinions expressed herein are my own except on Tuesday when the second card is not turned up otherwise it ain't worth squat.

© Copyright 2010

Postback, UpdatePanel or JSON which one?

Microsoft introduced AJAX as an add on to .NET 2.0. Today, AJAX is now included as part of the core release of .NET 3.5. With this technology it is significantly easier for developers to implement Web 2.0 type applications. Rather than posting the entire form and receiving the entire page, the browser can send a partial request and receive a partial response. This is known as partial rendering. In some cases, all that is required is adding a ScriptManager and an UpdatePanel control and you are done. If you wish to reduce the payload even further you can use JavaScript Object Notation (JSON) and reduce the request and response footprint even further. In this post, I will investigate each of these technics, that is, the postback, UpdatePanel and JSON and hopefully give some insight on when each is appropriate.

Prerequisites

  1. Visual Studio 2008. Visual Web Developer Express 2008 should be fine. This post will be using VS2008.
  2. SQL Server with the Northwind database. The express ver1sion should be fine.

Initial Setup

Start Visual Studio 2008 and create a new web site. Delete the default.aspx web form that was added. When done your solution should be similar to the following:

Figure 1: Initial Solution

F1 Initial Solution 

Next add a LINQ To SQL class to the web site. But before you do this make sure you have a data connection to the Northwind database. Right click on the web site and select Add New Item. Select LINQ To SQL Class and name it Northwind.dbml. The Add New Item dialog is shown in Figure 2.

Figure 2: Add LINQ To SQL Class

F2 Add LINQ To SQL Class

A dialog will appear asking whether you would like to place the LINQ To SQL class into the App_Code folder, answer yes. For this scenario, we will be constructing a query that returns all the products for a customer using postal code to identify the customer. This requires that we add the Customers, Orders, Order Details and Products table to the designer surface. In the Server Explorer, navigate to the Northwind connection (if it doesn't already exist then add the connection) and expand the tables node. Select each table and drag them to the designer surface. Once completed the designer window should appear similar to the following:

Figure 3: LINQ To SQL Object Model

F3 LINQ To SQL Object Model

Behind the scenes LINQ To SQL is generating object classes that mirrors the tables that were added to the designer surface. To view the source for these classes use the Class View window. There you should see the Customer, Order, Order_Detail and Product classes. You may need to save the dbml file before these classes become visible in the Class View. One last point the dbml file is an XML file that describes schema for tables. This XML file is used to generate the object classes.

The next step is to add the code that will be responsible for retrieving products by postal code. Here we will use a LINQ query and the query will return a ProductsByPostalCode object that is serializable. This serialization will be important when we implement code that uses JSON. Right click the APP_Code folder and select the Add New Item menu item. Next select the class icon and choose Products.vb as the name for the file. Finally, add the code in Listing 1 to the Products class.

Listing 1: Code to Retrieve Products by Postal Code.

Imports System

Imports System.ServiceModel

Imports System.Runtime.Serialization

 

Public Class Products

 

    Public Function GetByPostalCode(ByVal pc As String) As List(Of ProductsByPostalCode)

 

        Dim db As New NorthwindDataContext()

        Dim products = From c In db.Customers _

                       Join o In db.Orders On o.CustomerID Equals c.CustomerID _

                       Join d In db.Order_Details On d.OrderID Equals o.OrderID _

                       Join p In db.Products On d.ProductID Equals p.ProductID _

                       Where c.PostalCode.Equals(pc) _

                       Select New ProductsByPostalCode With { _

                            .CompanyName = c.CompanyName, _

                            .Quantity = d.Quantity, _

                            .ProductName = p.ProductName, _

                            .PostalCode = c.PostalCode, _

                            .Phone = c.Phone _

                        }

        Return products.ToList

 

    End Function

 

End Class

 

<DataContract()> _

Public Class ProductsByPostalCode

 

    Private _CompanyName As String

    <DataMember()> _

    Public Property CompanyName() As String

        Get

            Return _CompanyName

        End Get

        Set(ByVal value As String)

            _CompanyName = value

        End Set

    End Property

 

    Private _ProductName As String

    <DataMember()> _

    Public Property ProductName() As String

        Get

            Return _ProductName

        End Get

        Set(ByVal value As String)

            _ProductName = value

        End Set

    End Property

 

    Private _Quantity As Short

    <DataMember()> _

    Public Property Quantity() As Short

        Get

            Return _Quantity

        End Get

        Set(ByVal value As Short)

            _Quantity = value

        End Set

    End Property

 

    Private _PostalCode As String

    <DataMember()> _

    Public Property PostalCode() As String

        Get

            Return _PostalCode

        End Get

        Set(ByVal value As String)

            _PostalCode = value

        End Set

    End Property

 

    Private _Phone As String

    <DataMember()> _

    Public Property Phone() As String

        Get

            Return _Phone

        End Get

        Set(ByVal value As String)

            _Phone = value

        End Set

    End Property

 

End Class

The method GetProductsByPostalCode creates a LINQ query that joins the Customers, Orders, Order_Details and Products objects and selects the CompanyName, ProductName, Quantity, PostalCode and Phone for the specified postal code. This data is returned in a custom object, ProductsByPostalCode. Using an anonymous type would not have been approp1riate here as serializing anonymous types is not easily done (not even sure if it is at all possible). The PoductsByPostalCode class is attributed with <DataContact> and the only method GetByPostalCode is attributed by <DataMember>. These attributes specify that the type defines or implements a data contract and is serializable. The <Serializable> attribute could have been used but <Data Contract> is the preferred WCF way.

That's it, the data access layer is complete.

 

Postback

Implementing the postback model is fairly straight forward. Add a web form to the web site and call the web form, Postback.aspx. Next add a TextBox, Button and GridView. Afterwards the markup should look like Listing 2.

List 2: Postback.aspx markup code. 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

      <asp:TextBox ID="txtPostalCode" runat="server"></asp:TextBox>

      <asp:Button ID="btnGetProducts" runat="server" Text="Get Products"></asp:Button>

      <br/>

      <asp:GridView ID="gvProducts" runat="server"></asp:GridView>

    </div>

    </form>

</body>

</html>

Next in the code behind add the following code that gets executed when the button is clicked. This code calls the GetByPostalCode method that was created earlier.

List 3: Postback.aspx.vb code behind.

    Protected Sub btnGetProducts_Click(ByVal sender As Object, ByVal e As System.EventArgs) _

    Handles btnGetProducts.Click

        Dim prod As New Products

        gvProducts.DataSource = prod.GetByPostalCode(txtPostalCode.Text)

        gvProducts.DataBind()

    End Sub

Now lets take a look at the payload of this web application. To do this we will use a Fiddler a great tool for monitoring HTTP traffic. First start Fiddler and then start the Postback.aspx. Enter the postal code 12209 and click the Get Products button. You should see a table with 12 products, as shown in Figure 4.

Figure 4: Products returned for postal code 12209.

F4 Postabackaspx Products for 12209

In Fiddler, select the postback.aspx URL session and then select the Performance Statistics tab. The bytes sent are 1522 and bytes received are 5,295. If you would like to see the raw data sent to and from the browser, double click the session in Fiddler and select the Raw tab. It is apparent that the entire form is sent to the server and the server sends the entire page back to the browser.

Figure 5: Raw request and Response from Fiddler

F5 Fiddler Request and Response 

 

Partial Rendering with the UpdatePanel

This time we will use the AJAX UpdatePanel to fetch the products. Adding an UpdatePanel is extremely simple, all you need to do is add a ScriptManager tag and then surround the portion of the page you wish to render partially with an UpdatePanel control. Add a new web form to the site and give it a name UpdatePanel. Next copy the markup from Postback.aspx to the UpdatePanel.aspx and similarly copy the code behind from Postback.aspx.vb to UpdatePanel.aspx.vb.

Drag and drop the AJAX ScriptManager from the toolbox to the UpdatePanel.aspx making sure that the <ScriptManager> tag appears after the <form> tag. The next step is to add the AJAX UpdatePanel control to the UpdatePanel.aspx markup. Again this is done by dragging and dropping the AJAX UpdatePanel control from the toolbox. Add the <ContentTemplate> tags within the the <UpdatePanel> tags. Lastly, cut the markup for the Button, TextBox and GridView controls and paste them within the <ContentTemplate> tags. If all is well you should have code resembling Listing 4.

Listing 4: Markup with the UpdatePanel Control

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

      <asp:ScriptManager ID="ScriptManager1" runat="server">

      </asp:ScriptManager>

    <div>

      <asp:UpdatePanel ID="UpdatePanel1" runat="server">

        <ContentTemplate>

          <asp:TextBox ID="txtPostalCode" runat="server"></asp:TextBox>

          <asp:Button ID="btnGetProducts" runat="server" Text="Get Products"></asp:Button>

          <br/>

          <asp:GridView ID="gvProducts" runat="server"></asp:GridView>       

        </ContentTemplate>

      </asp:UpdatePanel>

    </div>

    </form>

</body>

</html>

I have not included the button event handler code as it is identical to that of the Postback.aspx.vb.

Now let's look at the payload of this page. Start Fiddler and then navigate to the UpdatePanel.aspx page. You may need to set the UpdatePanel.aspx as the Start page. Next enter the postal code 12209 and select the Get Products button. The output from the page will be the same as in Figure 4. In Fiddler select the session that corresponds to the button click and then select the Performance Statistics tab. Fiddler reports that the bytes sent are 933 and bytes received are 5124. Not a huge saving, but let's not forget that the page consists almost entirely of the grid. What if the page contained other content that did not require refreshing then the payload difference between the postback model and the UpdatePanel would be significant. Figure 6 shows the request and response for the UpdatePanel. Note that the response only contains the markup that appears within the UpdatePanel. This is what is meant by partial rendering; only the markup that is requested is sent back in the HTTP response.  

Figure 6: UpdatePanel: Request and Response

F6 UpdatePanel Request and Response

This is great. By adding only a few lines of markup you can significantly reduce the payload of your page.

 

WCF and JSON

The last method I will demonstrate reduces the payload even more, but at a cost. JavaScript Object Notation (JSON) is an extremely terse way of serializing objects. Basically, JSON uses name-value pairs to serialize the object. XML serialization could be used, instead, but it would be more verbose and more importantly there is no built-in JavaScript support for XML serialization. Windows Communication Foundation (WCF) makes it extremely simple to create a service that uses JSON as it's transport mechanism.

To add an AJAX-enabled WCF Service, right click the web site and select Add New Item. The Add New Item dialog appears. Select the AJAX-enabled WCF Service template and name it ProductService.svc. Figure 7 shows the Add New Item dialog.

Figure 7: Add AJAX-enabled WCF Service.

F7 Add AJAX-enable WCF Service 

Adding the AJAX-enabled WCF Service causes three things to happen:

  1. ProductService.svc file is added to the web site. This is analogous to the asmx file generated file in web services.
  2. ProductService.vb file is added in the App_Code folder. This the code behind for the service. Remove the AspNetCompatibility attribute.
  3. The <system.serviceModel> node containing WCF configuration is added to the web.config file. Remove the line <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> from the web.config.

I've had issues with keeping the ASP.NET Compatibility setting. For some reason the client browser, at runtime, does not recognize the namespace (in this case CynotWhyNot). This is strange as intellisense recognizes the namespace.  

By default, the WCF service added will use JSON for serialization. Changing it to use XML requires a change to the <behaviors> section in the web.config. In order to use this service, changes are required to ProductService.vb, namely, we need to add the code to call the data access code. Listing 5 contains the necessary changes to call the Products GetByPostalCode method.

Listing 5: ProductService.vb

Imports System.ServiceModel

Imports System.ServiceModel.Activation

Imports System.ServiceModel.Web

 

<ServiceContract(Namespace:="CynotWhyNot.WhichOne")> _

Public Class ProductService

 

    <OperationContract()> _

    Public Function GetProducts(ByVal pc As String) As List(Of ProductsByPostalCode)

        Dim nwp As New Products

        Dim products As New List(Of ProductsByPostalCode)

        products = nwp.GetByPostalCode(pc)

        Return products

    End Function

 

End Class

Some points of interest:

  1. The <ServiceContract> attribute is added at the class level. All interfaces that are to be exposed as a service must have this attribute. Interestingly, when adding an AJAX-enabled WCF service no interface is generated. I have been looking for an explanation for why it behaves this way as I was under the impression that all WCF services must implement an interface that is attributed by the <ServiceContract> attribute. I have come across a few web casts that mention this as a convenience. Nonetheless it works fine.  It is good practise to add a namespace to avoid collisions. 
  2. The <OperationContract> attribute is added to the GetProducts method. The <OperationContract> attribute exposes the method as a service operation.

The WCF framework will automatically generate the JavaScript code required to invoke this service. To view the generated JavaScript, navigate the browser to the service and then  append /js to the URL. I am using FireFox here as it allows the view of the code directly in the browser. IE, on the other hand, r1equires that the JavaScript be saved to a file.

Figure 8: Generated JavaScript to Invoke the Service. 

F8 Javascript generated code

Note the function CynotWhyNot.WhichOne.ProductService.GetProducts. This will be the JavaScript function that will be called to asynchronously invoke the server side service.

With the WCF service in place we can now concentrate on the aspx page. This page will need to call the service, retrieve the product data from the call to the service and finally render the data.  Yes, dare I say it we need to write JavaScript. This is what I meant by there is a cost and that cost is coding HTML DOM using JavaScript.

Add a new web form to the web site and call it JSON.aspx. Next add the following code to JSON.aspx.

Listing 6: JSON.aspx Markup and Code

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>Untitled Page</title>

</head>

 

<script type="text/javascript">

 

  function getProducts() {

    var postalCode = document.getElementById('txtPostalCode');

    CynotWhyNot.WhichOne.ProductService.GetProducts(postalCode.value,onGetProductsComplete);

  }

 

  function onGetProductsComplete(products) {

    clearRows();

    //If products are returned then go ahead and add rows to the table.

    if (products.length > 0)

    {

        for(var i = 0; i < products.length; i++)

        {         

            var product = products[i];

            addRow(

                product.CompanyName,

                product.Phone,

                product.PostalCode,

                product.ProductName,

                product.Quantity

            );

        }

    }

  }

 

  var c = "#EFF3FB";

  function addRow(company,phone,postal,product,quantity) {

    if (c == "#EFF3FB") { c = "white"; } else { c = "#EFF3FB"; }

    var table = document.getElementById('tblProducts');

    var row = table.insertRow(table.rows.length);

    row.bgColor = c;

    row.insertCell(0).appendChild(document.createTextNode(company));

    row.insertCell(1).appendChild(document.createTextNode(postal));

    row.insertCell(2).appendChild(document.createTextNode(phone));

    row.insertCell(3).appendChild(document.createTextNode(product));

    row.insertCell(4).appendChild(document.createTextNode(quantity));

  }

 

  function clearRows() {

    var table = document.getElementById('tblProducts');

    for(var i = table.rows.length - 1; i > 0 ; i--)

    {

      table.deleteRow(i);

    }

  }

 

</script>

 

<body>

    <form id="form1" runat="server">

    <div>

 

      <asp:ScriptManager ID="ScriptManager1" runat="server">

        <Services>

          <asp:ServiceReference Path="~/ProductService.svc" />

        </Services>

      </asp:ScriptManager>

 

      <asp:TextBox ID="txtPostalCode" runat="server"></asp:TextBox>

      <asp:Button ID="btnGetProducts" runat="server" Text="Get Products" OnClientClick="getProducts(); return false;"></asp:Button>

 

      <br/>

 

      <asp:Table ID="tblProducts" runat="server" EnableViewState="false" >

          <asp:TableHeaderRow BackColor="#DDDDDD" Font-Size="Small">

              <asp:TableHeaderCell HorizontalAlign="Left" Width="400px"><h2>Company</h2></asp:TableHeaderCell>

              <asp:TableHeaderCell HorizontalAlign="Left" Width="150px"><h2>Postal</h2></asp:TableHeaderCell>

              <asp:TableHeaderCell HorizontalAlign="Left" Width="150px"><h2>Phone</h2></asp:TableHeaderCell>

              <asp:TableHeaderCell HorizontalAlign="Left" Width="350px"><h2>Product</h2></asp:TableHeaderCell>

              <asp:TableHeaderCell HorizontalAlign="Left" Width="100px"><h2>Quantity</h2></asp:TableHeaderCell>

          </asp:TableHeaderRow>

      </asp:Table>

 

    </div>

    </form>

</body>

</html>

Let's breakdown this code.

The <ScriptManager> tag is added so that we can add a reference to ProductService.srv service. This will automatically cause the JavaScript generated code (see Figure 8) to be uploaded to the client browser. An added feature is that design time intellisense support for this JavaScript is included. I was impressed when I first saw this. The addition of the <ScriptManager> tag also causes the broser to upload the Microsoft Ajax library.

The button uses the OnClientClick attribute to call the custom function getProducts and then returns false. Returning false is needed otherwise the click action will cause a postback and we want to prevent this from happening.

The GridView has been replaced with a table and only the table header is added. The table rows containing the product information will be added using JavaScript.

Finally, we have four JavaScript functions contained within the script block. The function getProducts calls the JavaScript service proxy CynotWhyNot.WhichOne.ProductService.GetProducts passing two parameters; postalCode.value and onGetProductsComplete. postalCode.value is the postal code entered in the text box and  onGetProductsComplete is a function callback that is called when the service has completed. There are two optional parameters that have been omitted for brevity; a callback to a function in case an error occurred in the service and userContext which can be any data the developer wishes to pass to the callback function when the service successfully completed (in our case onGetProductsComplete).

The function onGetProductsComplete is called asynchronously when the service completes provided there were no errors. Any return value from the service call is returned as the first parameter to the callback. The great thing is this parameter is automatically de-serialized for you. That is, the parameter, products, in the callback to onGetProductsComplete  is a JavaScript object that parallels the server side object List(Of ProductsByPostalCode). Since JavaScript has no understanding of managed generics, the JavaScript object is returned as an array of objects of type ProductsByPostalCode.

The remaining JavaScript code is responsible for adding rows to the table. I  won't bore you with the details of it.

Run this page, enter a postal code of 12209 and then select the Get Products button. The resulting page is shown in figure 9.

Figure 9: Running JSON.aspx.

F9 Running JSON.aspx

The question is what kind of payload results when we use JSON. Start Fiddler and then browse to JSON.aspx, enter 12209 as the postal code and then select the Get Products button. Select the session in Fiddler and then click the Performance Statistics tab. The bytes sent is now only 546 and bytes received is 2408. Down by a factor of 2 from the previous ways. Now let's take a look at the actual data sent across the wire. Double click on the session in Fiddler and select the raw tab. The results are shown in Figure 10.

Figure 10: Data transmitted using JSON

F10 Data JSON

The request is reduced to {"pc":"12209"} and the response is reduced to a collection of name-value pairs. Now that's compact!

 

Summary

We started off by asking the question, Which One?

The traditional post back method is straight forward to code but has the largest payload as it always sends the entire form to the server and the server responds by sending the complete markup. The UpdatePanel is great way of reducing the payload. Implementation can be as simple as adding a few lines to the aspx file. Even though the payload is reduced, the server processing remains unaltered as the complete page life cycle process is run. Nonetheless, it is great way to improve performance. Lastly, JSON with WCF is by far the best way of minimizing payload. But this comes at a cost, the developer is required to write JavaScript code.

What I typically suggest:

  • Use postback if you are saving data, e.g., an entry form.
  • Use UpdatePanel when you need to update a portion of the screen that was initiated by the user.
  • Use JSON when you want to periodically update a portion of the screen. An example of this might be a stock price updated every minute.

 

Guess the movie

Out of order, I show you out of order. You don't know what out of order is, Mr. Trask. I'd show you, but I'm too old, I'm too tired, I'm too fuckin' blind. If I were the man I was five years ago, I'd take a FLAMETHROWER to this place! Out of order? Who the hell do you think you're talkin' to? I've been around, you know? There was a time I could see. And I have seen. Boys like these, younger than these, their arms torn out, their legs ripped off. But there isn't nothin' like the sight of an amputated spirit. There is no prosthetic for that. You think you're merely sending this splendid foot soldier back home to Oregon with his tail between his legs, but I say you are... executin' his soul! And why? Because he's not a Bairdman. Bairdmen. You hurt this boy, you're gonna be Baird bums, the lot of ya. And Harry, Jimmy, Trent, wherever you are out there, FUCK YOU TOO!

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET | JSON | WCF
Posted by CynotWhyNot on Wednesday, April 23, 2008 11:26 AM
Permalink | Comments (72) | Post RSSRSS comment feed

Related posts

Comments

swimming pools construction us

Saturday, September 12, 2009 4:06 AM

swimming pools construction

I loved the way you exlained things. Much better many here


Regards

Martinez

Raleigh Custom Cabinets us

Friday, September 18, 2009 10:44 AM

Raleigh Custom Cabinets

I posted your blog to my facebook group


Regards
Courtney

web 2.0 marketing plan us

Thursday, October 08, 2009 7:16 AM

web 2.0 marketing plan

I digged this for more news from you.



Regards and respect
Ziggy

watch one tree hill online us

Monday, October 12, 2009 1:57 AM

watch one tree hill online

I digged this for more news from you.



Regards and respect
Licky

seattle dui attorneys us

Monday, November 16, 2009 3:29 AM

seattle dui attorneys

Hi nice to read this I realy like to


Regards
Golden


discount bag US

Tuesday, December 01, 2009 1:48 PM

discount bag

Funny, I actually had this on my mind a few days ago and now I come across your blog.

Chinese Translation Service us

Wednesday, December 16, 2009 12:50 AM

Chinese Translation Service

Nice work. Very informative article. I will love to bookmark you for the future preferences. Thanks for sharing.




Regards
Pender


adidas sneakers US

Thursday, December 24, 2009 4:39 PM

adidas sneakers

Comfortabl y, the article is in reality the best on this valuable topic. I harmonise with your conclusions and will thirstily look forward to your coming updates. Just saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will instantly grab your rss feed to stay privy of any updates. Fabulous work and much success in your business dealings!

discount designer handbags US

Thursday, December 31, 2009 12:18 PM

discount designer handbags

If you need to buy discount gucci bags, you can just type bagsvendor.com in you browser address line and find out the gucci bags on big sale in discounted price. The information below is only introducing the discount news about gucci bags and gucci handbags. A woman leads the world accounting her gucci bag. But then we must also remember that there is a well discount news that has to see. It is a common complaint that women having their share is not large enough to hold all your belongings necessary, such as discount gucci bags, designer bags. This gucci bags you can find in bagsvendor.com is that the person is unable to organize things properly. Each discount bag has a clear purpose and objects you choose to take the bag must be compatible with the purposes for which it is purchased in your mind. We can meet the wide range of needs that are part of the common things for a trip on a beautiful handbag, bags or purses. Thus, while the discounted gucci bags needs, here are some points that may be useful to organize the contents of the discount gucci bag. Even it is a discounted price gucci bags, but it has high quality. The quality of materials used with the gucci bag is leather, suede or cotton. These materials can be sure that they are not less than 100% authentic and of excellent quality discount bags. Accessories and decorative items from the discount gucci bag, such as hinges, chains, rings and belt buckles are higher that other bags. Some designers in the Gucci company will even give as a repair or replacement free of charge in a period of time to ensure that their discount handbags are offered in a different league than the shares that you can find at any mall or online store. Designer Gucci bags can be changed to discounted gucci bags. This is a big news about handbags on sale. Brands are just called by many famous fashion people, and can be done with any discounted news. Just find more in bagsvendor.com

air jordan US

Friday, January 01, 2010 11:12 PM

air jordan

In winnersneaker, these Nike Air Jordan shoes were associated with sport, fashion and basketball. The Nike Air Jordan sneakers were a way to hide some of the smaller sizes, or raise an important NBA star to even higher levels to the count. Nike Air Jordan shoes, but also less fashionable of Air Jordan history. Which were commonly used by high-ranking customers in NBA during the 19th century and were used in the 20th century to let the putrid mud in the streets, all you know is that you can find many discounted Air Jordan shoes in winnersneaker.com. Existing Air Jordan retro sneakers in the United States and Europe retails do not feel in fashion until the new Air Jordan shoes come in the street. At first the Air Jordan 1 shoes important wearing for young sport men, but once reigned basketball, Jordan shoes became the must-have fashion accessory for young people in the basketball playground. These Air Jordan original shoes were all to make a statement vividly. Air Jordans like Air Jordan 23 and Air Jordan 6 wore basketball shoes kiss in the context of his people larger than life. Wish you find a suitable Air Jordan shoes in winnersneaker.com.

colon cleanse us

Friday, February 19, 2010 11:29 AM

colon cleanse

You will never do anything in this world without courage. It is the greatest quality of the mind next to honour.

designer bags US

Sunday, March 07, 2010 4:04 PM

designer bags

Substantially, the article is in reality the sweetest on this precious topic. I harmonise with your conclusions and will thirstily look forward to your upcoming updates. Saying thanks will not just be sufficient, for the phenomenal clarity in your writing. I will directly grab your rss feed to stay abreast of any updates. Pleasant work and much success in your business efforts!

discount designer bags US

Monday, March 08, 2010 10:54 PM

discount designer bags

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

discount handbags US

Tuesday, March 09, 2010 2:34 PM

discount handbags

I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!

nba basketball shoes US

Wednesday, March 10, 2010 9:45 PM

nba basketball shoes

There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.

wholesale shoes from china US

Wednesday, March 10, 2010 11:28 PM

wholesale shoes from china

You did the a great work writing and revealing the hidden beneficial features of BlogEngine.Net, that I found it was popularly used by bloggers nowadays. I think BE has emerged to be one of the best blogging platform right now. I wish you good luck with your blogging experiences.

designer handbag US

Thursday, March 11, 2010 2:48 AM

designer handbag

Your blog is perfect, and I like this article. I find the information I need. I think I can find more useful information here, thanks.

lebron james shoes US

Thursday, March 11, 2010 6:47 AM

lebron james shoes

Funny, I actually had this on my mind a few days ago and now I come across your blog.

china shoes US

Friday, March 12, 2010 12:06 AM

china shoes

I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!

wholesale shoes sale US

Friday, March 12, 2010 2:51 PM

wholesale shoes sale

Comfortabl y, the article is in reality the best on this valuable topic. I harmonise with your conclusions and will thirstily look forward to your coming updates. Just saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will instantly grab your rss feed to stay privy of any updates. Fabulous work and much success in your business dealings!

adidas shoes US

Sunday, March 14, 2010 3:26 AM

adidas shoes

Nice content, I trust this is a nice blog. Wish to see fresh content next time.

wholesale shoes sale US

Sunday, March 14, 2010 3:27 AM

wholesale shoes sale

Comfortabl y, the article is in reality the best on this valuable topic. I harmonise with your conclusions and will thirstily look forward to your coming updates. Just saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will instantly grab your rss feed to stay privy of any updates. Fabulous work and much success in your business dealings!

designer handbag US

Sunday, March 14, 2010 4:05 AM

designer handbag

Nice content, I trust this is a nice blog. Wish to see fresh content next time.

basketball shoes sale US

Sunday, March 14, 2010 4:50 AM

basketball shoes sale

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

air jordan sale US

Sunday, March 14, 2010 4:51 AM

air jordan sale

Thanks for your article.

designer bag US

Sunday, March 14, 2010 4:54 AM

designer bag

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

paul sneakers US

Sunday, March 14, 2010 6:20 AM

paul sneakers

You have a point. Very insightful. A nice different perspective

air max US

Sunday, March 14, 2010 8:07 AM

air max

Hey, guy, your blog is nice. It can bring me many useful information.

nike air max US

Monday, March 15, 2010 12:56 AM

nike air max

There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.

paul sneakers US

Monday, March 15, 2010 5:58 PM

paul sneakers

Yeah, you are right, I agree with you.

designer handbag US

Thursday, March 25, 2010 5:35 AM

designer handbag

I really appreciate this wonderful post that you have provided for us. I assure this would be beneficial for most of the people.

nike shox shoes US

Thursday, March 25, 2010 7:34 AM

nike shox shoes

There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.

kobe sneakers US

Thursday, March 25, 2010 10:52 AM

kobe sneakers

There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.

nike air force 1 US

Thursday, March 25, 2010 4:32 PM

nike air force 1

Easily, the post is really the greatest on this laudable topic. I concur with your conclusions and will thirstily look forward to your future updates. Saying thanks will not just be sufficient, for the fantasti c lucidity in your writing. I will instantly grab your rss feed to stay privy of any updates. Solid work and much success in your business enterprize!

basketball sneakers US

Thursday, March 25, 2010 6:25 PM

basketball sneakers

What a great info, thank you for sharing. this will help me so much in my learning.

supra shoes US

Friday, March 26, 2010 6:54 AM

supra shoes

I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.

kobe sneakers US

Friday, March 26, 2010 10:15 AM

kobe sneakers

You did the a great work writing and revealing the hidden beneficial features of BlogEngine.Net, that I found it was popularly used by bloggers nowadays. I think BE has emerged to be one of the best blogging platform right now. I wish you good luck with your blogging experiences.

wholesale shoes sale US

Saturday, March 27, 2010 9:04 AM

wholesale shoes sale

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

china shoes products US

Saturday, March 27, 2010 5:18 PM

china shoes products

Easily, the post is really the greatest on this laudable topic. I concur with your conclusions and will thirstily look forward to your future updates. Saying thanks will not just be sufficient, for the fantasti c lucidity in your writing. I will instantly grab your rss feed to stay privy of any updates. Solid work and much success in your business enterprize!

basketball sheos US

Saturday, March 27, 2010 6:01 PM

basketball sheos

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

discount designer bags US

Sunday, March 28, 2010 7:12 AM

discount designer bags

Substantially, the article is in reality the sweetest on this precious topic. I harmonise with your conclusions and will thirstily look forward to your upcoming updates. Saying thanks will not just be sufficient, for the phenomenal clarity in your writing. I will directly grab your rss feed to stay abreast of any updates. Pleasant work and much success in your business efforts!

air yeezy US

Sunday, March 28, 2010 7:55 AM

air yeezy

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

air max 90 US

Sunday, March 28, 2010 9:00 AM

air max 90

I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!

basketball shoes sale US

Sunday, March 28, 2010 5:51 PM

basketball shoes sale

I admire the valuable information you offer in your articles. I will bookmark your blog and have my children check up here often. I am quite sure they will learn lots of new stuff here than anybody else!

air max 360 US

Tuesday, March 30, 2010 6:13 PM

air max 360

Thanks for your article.

air yeezy US

Wednesday, March 31, 2010 7:17 AM

air yeezy

I really appreciate this wonderful post that you have provided for us. I assure this would be beneficial for most of the people.

nike air max US

Wednesday, March 31, 2010 8:32 AM

nike air max

What a great info, thank you for sharing. this will help me so much in my learning.

nike air yeezy US

Saturday, April 03, 2010 7:55 AM

nike air yeezy

While this subject can be very touchy for most people, my opinion is that there has to be a middle or common ground that we all can find. I do appreciate that youve added relevant and intelligent commentary here though. Thank you!

kobe sneakers US

Saturday, April 03, 2010 11:35 AM

kobe sneakers

Hey, guy, your blog is nice. It can bring me many useful information.

discount designer handbags US

Saturday, April 03, 2010 4:30 PM

discount designer handbags

Comfortabl y, the article is in reality the best on this valuable topic. I harmonise with your conclusions and will thirstily look forward to your coming updates. Just saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will instantly grab your rss feed to stay privy of any updates. Fabulous work and much success in your business dealings!

air yeezy sneakers US

Saturday, April 03, 2010 5:54 PM

air yeezy sneakers

Comfortabl y, the article is in reality the best on this valuable topic. I harmonise with your conclusions and will thirstily look forward to your coming updates. Just saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will instantly grab your rss feed to stay privy of any updates. Fabulous work and much success in your business dealings!

nba stars shoes US

Monday, April 05, 2010 6:25 PM

nba stars shoes

I find your blog in google. And I will be back next time, thanks.

james shoes sale US

Wednesday, April 07, 2010 4:29 PM

james shoes sale

Your blog seems interesting.Regards,Kevin.

discount designer handbag US

Friday, April 09, 2010 5:22 AM

discount designer handbag

While this subject can be very touchy for most people, my opinion is that there has to be a middle or common ground that we all can find. I do appreciate that youve added relevant and intelligent commentary here though. Thank you!

air jordan US

Friday, April 09, 2010 6:13 AM

air jordan

There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.

discount designer handbag US

Saturday, April 10, 2010 5:50 PM

discount designer handbag

You have a point. Very insightful. A nice different perspective

air max sale US

Sunday, April 11, 2010 5:06 PM

air max sale

I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.

wholesale shoes from china US

Monday, April 12, 2010 6:00 PM

wholesale shoes from china

Funny, I actually had this on my mind a few days ago and now I come across your blog.

air max sneaker US

Monday, April 12, 2010 6:02 PM

air max sneaker

I was thinking of using BlogEngine but then I saw that most of the sites I looked either had comments full of spam or they had simply closed the comments altogether. I hope that you have been able to combat the spam because at the moment it is something that is making me stay away from BE.

nike shox US

Wednesday, April 14, 2010 2:18 PM

nike shox

Your blog seems interesting.Regards,Kevin.

nike air jordan US

Saturday, April 17, 2010 4:53 PM

nike air jordan

Comfortabl y, the article is in reality the best on this valuable topic. I harmonise with your conclusions and will thirstily look forward to your coming updates. Just saying thanks will not just be sufficient, for the wonderful clarity in your writing. I will instantly grab your rss feed to stay privy of any updates. Fabulous work and much success in your business dealings!

chinese shoes wholesale US

Tuesday, April 20, 2010 6:51 PM

chinese shoes wholesale

I was thinking of using BlogEngine but then I saw that most of the sites I looked either had comments full of spam or they had simply closed the comments altogether. I hope that you have been able to combat the spam because at the moment it is something that is making me stay away from BE.

chinese shoes wholesale US

Wednesday, April 28, 2010 5:57 PM

chinese shoes wholesale

I find your blog in google. And I will be back next time, thanks.

nba stars shoes US

Wednesday, April 28, 2010 7:04 PM

nba stars shoes

This is just the information I am finding everywhere. Thanks for your blog, I just subscribe your blog. This is a nice blog.

air jordan US

Friday, May 28, 2010 10:41 PM

air jordan

Your blog is perfect, and I like this article. I find the information I need. I think I can find more useful information here, thanks.

discount louis vuitton US

Saturday, July 03, 2010 10:17 AM

discount louis vuitton

Nice content, I trust this is a nice blog. Wish to see fresh content next time.

chanel bags online US

Friday, July 23, 2010 5:18 AM

chanel bags online

Happy to see your blog as it is just what I’ve looking for and excited to read all the posts.

designer jeans US

Friday, August 20, 2010 9:23 PM

designer jeans

Hey, guy, your blog is nice. It can bring me many useful information.

new designer jeans US

Saturday, August 21, 2010 5:25 AM

new designer jeans

I was very pleased to find this site.I wanted to thank you for this great read!! I definitely enjoying every little bit of it and I have you bookmarked to check out new stuff you post.

nike air max US

Saturday, August 21, 2010 3:06 PM

nike air max

Have you ever considered adding more videos to your blog posts to keep the readers more entertained? I mean I just read through the entire article of yours and it was quite good but since I am more of a visual learner,I found that to be more helpful well let me know how it turns out.

sandals on sale US

Wednesday, August 25, 2010 12:19 PM

sandals on sale

Hey, guy, your blog is nice. It can bring me many useful information.

gucci brand bags US

Friday, September 03, 2010 12:12 AM

gucci brand bags

Nice content, I trust this is a nice blog. Wish to see fresh content next time.

Add comment


(Will show your Gravatar icon)  

  Country flag

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



Live preview

Saturday, September 04, 2010 1:23 AM