Computer Magic
Software Design Just For You
 
 

ASP.NET 2.0 – New deployment issues

December 19th, 2005

Today I deployed my first ASP.NET 2.0 application. The new copy file
interface in Visual Studio 2005 is nice, but confused me at first as there is now a publish interface in addition to the copy interface. While both
seem to work just fine, neither one seems to be smart enough to push
dependant objects to the server. The use of the new Report Viewer control on the client end caused the application to fail on the server. It was
unable to find the control in the Global Assembly Cache (GAC) on the server. I tried a few things including copying the files to the server, and downloading the redistrabutable from MS (why didn’t this work!?!), and even trying to manually register the control in the GAC (regasm). None of these things seemed to solve the problem. Finally, I just copied the required DLL to the bin folder in the web application. This put the control in a location that the application could find it and everything seemed to work fine after that. It would have been nice if MS had automated this or at least shown a warning and saved me a headache. This solution, so so simple, could have saved me an hour or two. Thats what you get for using new technologies though.

This brings up the question, was it worth it to use the Report Viewer
control? The answer is a resounding YES! The final solution worked great! It outputs a PDF version of a report and opens it in a popup window for easy viewing. Very slick, and very easy to work with once you know how (better start brushing up on your custom code capabilities).

Ray Pulsipher

Owner

Computer Magic And Software Design

Reduce the size of your data grid viewstate in ASP.NET

December 16th, 2005

This document is property of Computer Magic And Software Design © 2004. It may not be redistributed or reproduced in any form without express written permission from the author.

Keywords: ASP.NET, Datagrid, Webforms, Sorting, Viewstate, Paging, Sort
Direction

Viewstate, a Datagrid and You


Working with the datagrid:

The initial reaction to working with the datagrid is WOW, this thing is
great! As you actually begin to use the thing though it quickly becomes
apparent that there are some limitations – mostly in the form of
inconvenience. The first thing many people notice is the obscene size of the viewstate when the datagrid is populated. Why does this occur? Simple. By default, the viewstate is on for all server side controls. That means all controls in the datagrid such as link buttons have an entry. If you are showing 10 rows with one Remove link per row, do the math, it begins to add up. In addition, each control that makes up the rendered datagrid also has viewstate properties (including the actual table row and table cells).
Think that’s all? Think again. The viewstate is stored in an encoded
format called Base 64. This format by its very nature causes about a 30% increase in data size. Now before you begin criticizing Microsoft for the bloat, you should be aware that the Base 64 encoding is one of the standards in use for transferring binary information in e-mail. E-mail, like HTML, uses a text based protocol. As such, the Base 64 encoding reduces the binary information to a safe and transmittable format. This also makes Base 64 encoded information fit nicely into a hidden input on a web page called __VIEWSTATE. Take a look at the example below.

<input type="hidden" name="__VIEWSTATE" 
value="dDwtMTkyNjUyMzE4Mjt0PDtsPGk8MD47PjtsPHQ8O2w8aTw0Pjs+O2w8dDw7bDxpPDEyPjtpPDEzPjs+O2w8dDw7bDxpPDA+Oz47bDx0PDtsPGk8MTc+O2k8MTk+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPEdvb2QgTW9ybmluZzs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjs+Pjs+Pjt0PDtsPGk8Mz47PjtsPHQ8O2w8aTwxPjtpPDM+Oz47bDx0PEAwPHA8cDxsPFZpcnR1YWxJdGVtQ291bnQ7UGFnZUNvdW50O18hSXRlbUNvdW50O18hRGF0YVNvdXJjZUl0ZW1Db3VudDtEYXRhS2V5czs+O2w8aTwxNDAyPjtpPDE0MT47aTwxMD47aTwxNDAyPjtsPD47Pj47PjtAMDxAMDxwPGw8SGVhZGVyVGV4dDs+O2w8aWQ7Pj47Ozs7 PjtAMDxwPGw8SGVhZGVyVGV4dDs+O2w8RXZlbnQ7Pj47Ozs7PjtAMDxwPGw8SGVhZGVyVGV4dDs+O2w8VHlwZTs+Pjs7Ozs+O0AwPHA8bDxIZWFkZXJUZXh0Oz47bDxDYXVzZWQgQnkgVXNlcjs+Pjs7Ozs+O0AwPHA8bDxIZWFkZXJUZXh0Oz47bDxMb2dnZWQgQXQgXDxJTUcgSEVJR0hUPThweCBXSURUSD04cHggQk9SREVSPTAgc3JjPScvYXJ0L2Rvd24ucG5nJyAvXD47Pj47Ozs7PjtAMDxwPGw8SGVhZGVyVGV4dDs+O2w8QWN0aW9uczs+Pjs7Ozs+Oz47Ozs7Ozs7Ozs+O2w8aTwwPjs+O2w8dDw7bDxpPDI+O2k8Mz47aTw0PjtpPDU+O2k8Nj47aTw3PjtpPDg+O2k8OT47aTwxMD47aTwxMT47PjtsPHQ8O2w8aTwwPjtpPDE+O2k8Mj47aTwzPjtpPDQ+O2k8NT47PjtsPHQ8cDx wPGw8VGV4dDs+O2w8NTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8RXZlbnQgU3Vic2NyaXB0aW9uIFJlbW92ZWQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFN1Y2Nlc3NBdWRpdDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDgvMTYvMjAwNCAxOjE1OjI4IFBNOz4+Oz47Oz47dDw7bDxpPDE+Oz47bDx0PHA8O3A8bDxvbmNsaWNrO2hyZWY7PjtsPHJldHVybiBjb25maXJtKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gcmVtb3ZlIHRoaXMgbm90aWZpY2F0aW9uIGl0ZW0/JylcOztqYXZhc2NyaXB0Ol9fZG9Qb3N0QmFjaygnbG5rUmVtb3ZlRXZlbnQnLCc1Jyk7Pj4+Ozs+Oz4+Oz4+O3Q8O2 w8aTwwPjtpPDE+O2k8Mj47aTwzPjtpPDQ+O2k8NT47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8Njs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8VXNlciBMb2cgT3V0Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxTdWNjZXNzQXVkaXQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPHJheXBAcGNhZG1pbi5jdGMuZWR1Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDw4LzE2LzIwMDQgMToxNTo0MyBQTTs+Pjs+Ozs+O3Q8O2w8aTwxPjs+O2w8dDxwPDtwPGw8b25jbGljaztocmVmOz47bDxyZXR1cm4gY29uZmlybSgnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIHJlbW92ZSB0aGlzIG5vdGlmaWNhdGlvbiBpdGVtPycpXDs7amF2YXNjcmlwdDpfX2RvUG9zdEJhY2soJ2xua1JlbW92ZUV2Z W50JywnNicpOz4+Pjs7Pjs+Pjs+Pjt0PDtsPGk8MD47aTwxPjtpPDI+O2k8Mz47aTw0PjtpPDU+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPDc7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFN1Y2Nlc3NmdWxsIExvZ2luOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxTdWNjZXNzQXVkaXQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPHJheXBAcGNhZG1pbi5jdGMuZWR1Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDw4LzE2LzIwMDQgMToxNTo0OSBQTTs+Pjs+Ozs+O3Q8O2w8aTwxPjs+O2w8dDxwPDtwPGw8b25jbGljaztocmVmOz47bDxyZXR1cm4gY29uZmlybSgnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIHJlbW92ZSB0aGlzIG5vdGlmaWNhdGlvbiBpdGVtPycpXDs7amF2YXNj cmlwdDpfX2RvUG9zdEJhY2soJ2xua1JlbW92ZUV2ZW50JywnNycpOz4+Pjs7Pjs+Pjs+Pjt0PDtsPGk8MD47aTwxPjtpPDI+O2k8Mz47aTw0PjtpPDU+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPDg7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFByb2ZpbGUgSW5mb3JtYXRpb24gU2F2ZWQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFN1Y2Nlc3NBdWRpdDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDgvMTYvMjAwNCAxOjE4OjM5IFBNOz4+Oz47Oz47dDw7bDxpPDE+Oz47bDx0PHA8O3A8bDxvbmNsaWNrO2hyZWY7PjtsPHJldHVybiBjb25maXJtKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gcmV tb3ZlIHRoaXMgbm90aWZpY2F0aW9uIGl0ZW0/JylcOztqYXZhc2NyaXB0Ol9fZG9Qb3N0QmFjaygnbG5rUmVtb3ZlRXZlbnQnLCc4Jyk7Pj4+Ozs+Oz4+Oz4+O3Q8O2w8aTwwPjtpPDE+O2k8Mj47aTwzPjtpPDQ+O2k8NT47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8OTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8UHJvZmlsZSBJbmZvcm1hdGlvbiBTYXZlZDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8U3VjY2Vzc0F1ZGl0Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxyYXlwQHBjYWRtaW4uY3RjLmVkdTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8OC8xNi8yMDA0IDE6Mjg6MzggUE07Pj47Pjs7Pjt0PDtsPGk8MT47PjtsPHQ8cDw7cDxsPG9uY2xpY2s7aHJlZjs+O2w8cmV0dX JuIGNvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byByZW1vdmUgdGhpcyBub3RpZmljYXRpb24gaXRlbT8nKVw7O2phdmFzY3JpcHQ6X19kb1Bvc3RCYWNrKCdsbmtSZW1vdmVFdmVudCcsJzknKTs+Pj47Oz47Pj47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjtpPDM+O2k8ND47aTw1Pjs+O2w8dDxwPHA8bDxUZXh0Oz47bDwxMDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8UHJvZmlsZSBJbmZvcm1hdGlvbiBTYXZlZDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8U3VjY2Vzc0F1ZGl0Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxyYXlwQHBjYWRtaW4uY3RjLmVkdTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8OC8xNi8yMDA0IDE6Mjk6NTYgUE07Pj47Pjs7Pjt0PDtsP Gk8MT47PjtsPHQ8cDw7cDxsPG9uY2xpY2s7aHJlZjs+O2w8cmV0dXJuIGNvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byByZW1vdmUgdGhpcyBub3RpZmljYXRpb24gaXRlbT8nKVw7O2phdmFzY3JpcHQ6X19kb1Bvc3RCYWNrKCdsbmtSZW1vdmVFdmVudCcsJzEwJyk7Pj4+Ozs+Oz4+Oz4+O3Q8O2w8aTwwPjtpPDE+O2k8Mj47aTwzPjtpPDQ+O2k8NT47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8MTE7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFByb2ZpbGUgSW5mb3JtYXRpb24gU2F2ZWQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFN1Y2Nlc3NBdWRpdDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjt0PHA8cDxsPFRl eHQ7PjtsPDgvMTYvMjAwNCAxOjM1OjU0IFBNOz4+Oz47Oz47dDw7bDxpPDE+Oz47bDx0PHA8O3A8bDxvbmNsaWNrO2hyZWY7PjtsPHJldHVybiBjb25maXJtKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gcmVtb3ZlIHRoaXMgbm90aWZpY2F0aW9uIGl0ZW0/JylcOztqYXZhc2NyaXB0Ol9fZG9Qb3N0QmFjaygnbG5rUmVtb3ZlRXZlbnQnLCcxMScpOz4+Pjs7Pjs+Pjs+Pjt0PDtsPGk8MD47aTwxPjtpPDI+O2k8Mz47aTw0PjtpPDU+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPDEyOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxQcm9maWxlIEluZm9ybWF0aW9uIFNhdmVkOz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxTdWNjZXNzQXVkaXQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7Pjt sPHJheXBAcGNhZG1pbi5jdGMuZWR1Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDw4LzE2LzIwMDQgMTo1MjowMiBQTTs+Pjs+Ozs+O3Q8O2w8aTwxPjs+O2w8dDxwPDtwPGw8b25jbGljaztocmVmOz47bDxyZXR1cm4gY29uZmlybSgnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIHJlbW92ZSB0aGlzIG5vdGlmaWNhdGlvbiBpdGVtPycpXDs7amF2YXNjcmlwdDpfX2RvUG9zdEJhY2soJ2xua1JlbW92ZUV2ZW50JywnMTInKTs+Pj47Oz47Pj47Pj47dDw7bDxpPDA+O2k8MT47aTwyPjtpPDM+O2k8ND47aTw1Pjs+O2w8dDxwPHA8bDxUZXh0Oz47bDwxMzs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8UHJvZmlsZSBJbmZvcm1hdGlvbiBTYXZlZDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dD s+O2w8U3VjY2Vzc0F1ZGl0Oz4+Oz47Oz47dDxwPHA8bDxUZXh0Oz47bDxyYXlwQHBjYWRtaW4uY3RjLmVkdTs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8OC8xNi8yMDA0IDE6NTU6NDAgUE07Pj47Pjs7Pjt0PDtsPGk8MT47PjtsPHQ8cDw7cDxsPG9uY2xpY2s7aHJlZjs+O2w8cmV0dXJuIGNvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byByZW1vdmUgdGhpcyBub3RpZmljYXRpb24gaXRlbT8nKVw7O2phdmFzY3JpcHQ6X19kb1Bvc3RCYWNrKCdsbmtSZW1vdmVFdmVudCcsJzEzJyk7Pj4+Ozs+Oz4+Oz4+O3Q8O2w8aTwwPjtpPDE+O2k8Mj47aTwzPjtpPDQ+O2k8NT47PjtsPHQ8cDxwPGw8VGV4dDs+O2w8MTQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFByb2Zpb GUgSW5mb3JtYXRpb24gU2F2ZWQ7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPFN1Y2Nlc3NBdWRpdDs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjt0PHA8cDxsPFRleHQ7PjtsPDgvMTYvMjAwNCAxOjU4OjMwIFBNOz4+Oz47Oz47dDw7bDxpPDE+Oz47bDx0PHA8O3A8bDxvbmNsaWNrO2hyZWY7PjtsPHJldHVybiBjb25maXJtKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gcmVtb3ZlIHRoaXMgbm90aWZpY2F0aW9uIGl0ZW0/JylcOztqYXZhc2NyaXB0Ol9fZG9Qb3N0QmFjaygnbG5rUmVtb3ZlRXZlbnQnLCcxNCcpOz4+Pjs7Pjs+Pjs+Pjs+Pjs+Pjt0PHA8cDxsPFRleHQ7PjtsPFBhZ2UgMSBvZiAxNDE7Pj47Pjs7Pjs+Pjs+ Pjs+Pjs+Pjs+Pjs+66yMSsisMGwArlHk3eyFer6hwP8=" /> 
Viewstate Size: 6681 Bytes (6.6K)  <-- Datagrids can cause much bigger values than this, even up to 10K+ 

Notice that the encoded value does not contain binary characters, non printable characters, or even “s that would interfere with the HTML. Very convenient.

Reducing Viewstate:

For many, the simple solution is to turn off the view state property in the datagrid. This results in a reduction to:

<input type="hidden" name="__VIEWSTATE" 
value="dDwtMTkyNjUyMzE4Mjt0PDtsPGk8MD47PjtsPHQ8O2w8aTw0Pjs+O2w8dDw7bDxpPDEyPjtpPDEzPjs+O2w8dDw7bDxpPDA+Oz47bDx0PDtsPGk8MTc+O2k8MTk+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPEdvb2QgTW9ybmluZzs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjs+Pjs+Pjt0PDtsPGk8Mz47PjtsPHQ8O2w8aTwzPjs+O2w8dDxwPHA8bDxUZXh0Oz47bDxQYWdlIDEgb2YgMTQxOz4+Oz47Oz47Pj47Pj47Pj47Pj47Pj47PlVonF2dspWHNoR0dJ1oK6nDCogm" /> 
Viewstate Size: 389 Bytes (.4k) <-- This is the viewstate required by 
other non datagrid related controls on my page.

While that looks great, you will soon find that many features are now
disabled. You can no longer sort properly, none of the datagrid events fire properly, you have to refresh your data every time the page refreshes, paging quits working, etc. Some have found ways to get around all this, but the time it takes often outweighs the benefits. Some opt at this point to go find another control and scrap the datagrid all together. I have found that the power of the datagrid is worth a little effort and that if you have a ready made template to draw from, then you can take advantage of the advanced features while still reducing your viewstate considerably.

A compromise:

We generally aren’t worried about a few hundred bytes, and it sure is a
whole lot of work to code around a datagrid that just lays there like a limp fish. The compromise here is to leave the viewstate on the datagrid on, but turn off the viewstate on all of the the components that end up on the page – namely the data row items. The datagrid has a handy event called ItemCreated which is fired once for every row that is rendered to the screen. When this event is fired, we can simply turn the viewstate off for this item. Keep in mind that this turns off the viewstate for the whole row. If the viewstate of a parent is off, all child controls also loose their viewstate. This means that any child cells, link buttons, etc loose their viewstate too. The code below shows the finished event as it would look in code.

Private Sub dgMyDgrid_ItemCreated(ByVal sender As Object, ByVal e As 
System.Web.UI.WebControls.DataGridItemEventArgs) Handles 
dgNotificationList.ItemCreated
        e.Item.EnableViewState = False
End Sub

Pretty simple eh? Lets look at the viewstate when the datagrid is enabled but its children aren’t.

<input type="hidden" name="__VIEWSTATE" value="
dDwtMTkyNjUyMzE4Mjt0PDtsPGk8MD47PjtsPHQ8O2w8aTw0Pjs+O2w8dDw7bDxpPDEyPjtpPDEzPjs+O2w8dDw7bDxpPDA+Oz47bDx0PDtsPGk8MTc+O2k8MTk+Oz47bDx0PHA8cDxsPFRleHQ7PjtsPEdvb2QgTW9ybmluZzs+Pjs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8cmF5cEBwY2FkbWluLmN0Yy5lZHU7Pj47Pjs7Pjs+Pjs+Pjt0PDtsPGk8Mz47PjtsPHQ8O2w8aTwxPjtpPDM+Oz47bDx0PEAwPHA8cDxsPFZpcnR1YWxJdGVtQ291bnQ7UGFnZUNvdW50O18hSXRlbUNvdW50O18hRGF0YVNvdXJjZUl0ZW1Db3VudDtEYXRhS2V5czs+O2w8aTwxNDAyPjtpPDE0MT47aTwxMD47aTwxNDAyPjtsPD47Pj47PjtAMDxAMDxwPGw8SGVhZGVyVGV4dDs+O2w8aWQ7Pj47Ozs7PjtAMDx wPGw8SGVhZGVyVGV4dDs+O2w8RXZlbnQ7Pj47Ozs7PjtAMDxwPGw8SGVhZGVyVGV4dDs+O2w8VHlwZTs+Pjs7Ozs+O0AwPHA8bDxIZWFkZXJUZXh0Oz47bDxDYXVzZWQgQnkgVXNlcjs+Pjs7Ozs+O0AwPHA8bDxIZWFkZXJUZXh0Oz47bDxMb2dnZWQgQXQgXDxJTUcgSEVJR0hUPThweCBXSURUSD04cHggQk9SREVSPTAgc3JjPScvYXJ0L2Rvd24ucG5nJyAvXD47Pj47Ozs7PjtAMDxwPGw8SGVhZGVyVGV4dDs+O2w8QWN0aW9uczs+Pjs7Ozs+Oz47Ozs7Ozs7Ozs+Ozs+O3Q8cDxwPGw8VGV4dDs+O2w8UGFnZSAxIG9mIDE0MTs+Pjs+Ozs+Oz4+Oz4+Oz4+Oz4+Oz4+Oz66V9WQsY6x9IVtOTOsjeJl7Y3I0Q==" /> 
Viewstate Size: 969 Bytes (1K)

969 – 389 = 580 Bytes. The 389 in this case is the viewstate from other
items on the page I am using as a reference. This means that the datagrid is now using about 580 Bytes instead of (6681 – 389 = 6292 Bytes). That’s quite a significant difference. The best part is that the events for
sorting and paging will still fire properly!

Were not done yet:

While the sorting and paging events still fire properly, you may find that events for data rows do not (e.g.: Remove link button to drop the selected record). If they do still work, that means that you probably populate your datagrid in the Page_Load event. An interesting thing about firing events for controls is that they have to be instantiated before or in the Page_Load event for their event to fire properly. Any events for controls that don’t exist yet when the event is ready to fire are simply dropped. Since any link buttons (or other controls) added to a data row are dynamic, the datagrid has to have already re-populated itself with these controls for them to fire events properly. Lets look at the example of clicking the remove button to delete a record. If a user views the datagrid, they see a list of data. When they click Remove, the Page_Load event fires, your code repopulates the datagrid with the current information, the Item Command event can now fire with the command name and command argument of the source control. Now since the data has changed, you may need to refresh your data source with the new information, then the result is rendered to the user. You may or may not have noticed that you refresh your datagrid twice.
Weather you use caching or other techniques to help speed this process,
binding data to your control multiple times.

Avoiding Multiple Refresh:

Be aware, that the datagrid itself isn’t dynamic, just its child items such as data rows. This being the case, events for the datagrid itself (sorting, paging, etc) should work just fine as long as it’s viewstate is enabled. I myself prefer to call my data refresh from the Page_PreRender event. By now, everything should be figured out, all events should have been fired, and all you need to do is grab the current data set (I also prefer to use data chunks in many cases, but that is another article in it self). This sounds good except that for a button in a data row to fire properly, it has to be created long before the PreRender event or the event will be dropped. An easy way to get around this is to hijack the event of another button. What is the difference between a link button in a data row and any other link button on the page? The main difference is that generally the ID or other primary key of the selected data indicating which item to remove, change, etc. Other than that, you just want an event to fire in response to the click.

Hijacking Events:

A data list with one hundred entries, each with its own remove link have one thing in common. However you implement the process, all those link buttons fire the same event with an id or some other primary key indicating which item to remove. This being the case, does it matter if the datagrid itself receives the event, or can another control all together receive the event? To keep the viewstate low, I opted to use another control completely. I
added a new link button to the page (outside the datagrid) and set its text property to “” (empty) and its CommandName property to “Remove”. You want this control to render to the page so don’t change the visible attribute, but you eliminate any visible sign it is there by clearing the text
property. Next, name the control so that it makes sense (in my case,
lnkRemove). We will make the command event fire when one of the Remove
links is clicked for a data item. Note that this new link control is not dynamic and therefore is instantiated already when it is time to fire
events. Create the Command event for the link button as shown below.

Private Sub lnkRemove_Command(ByVal sender As Object, ByVal e As 
System.Web.UI.WebControls.CommandEventArgs) Handles lnkRemoveEvent.Command   ' NOTE: the last_event_arg variable is a global variable and will be 
covered elsewhere.
        Dim id As Int64
        Try
            id = Convert.ToInt64(last_event_arg)  ' Try to convert the 
argument to a numeric value
        Catch ex As Exception
            id = 0
        End Try
        RemoveItemItem(id)  ' This function contains the logic to actually remove the item from the database, etc..
End Sub

Now that we have an event waiting to fire, we can set all of our Remove
links in the datagrid to use it. Because these datagrid link buttons are all created dynamically, we have to do the hooking in code. For each row to be displayed, the ItemDataBound event gets fired. During this process we can add a nice javascript confirm message (are you sure you want to remove) and at the same time hijack the event of our stray link button thereby sending all events from any of the datagrid remove links to the stray link buttons event handler.

Private Sub dgMyDataGrid_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles 
dgNotificationList.ItemDataBound
 'NOTE: We only want to change items or alt items.  If we try this on 
header, footer, etc. rows, it won't work (they shouldn't have remove 
buttons).
        If (e.Item.ItemType = ListItemType.AlternatingItem Or 
e.Item.ItemType = ListItemType.Item) Then
            Dim lnk As LinkButton
            Dim ds As Data.Common.DbDataRecord  ' NOTE: I believe this 
datatype changes depending on what is set to the datasource property
      ' of the datagrid.  I am using a DataReader, where I believe a 
datarowview object should be used when bound to a dataset
            ds = CType(e.Item.DataItem, Data.Common.DbDataRecord)
            lnk = 
CType(e.Item.Cells(2).FindControl("lnkRemoveNotification"), LinkButton)  ' Find the current link button
            If (Not lnk Is Nothing) Then
     ' Add the javascript confirm box so they have to click yes to remove
                lnk.Attributes.Add("onclick", "return confirm('Are you sure you want to remove this notification item?');") 
     ' This is where we hijack the post back event handler of the stray link button.  This allows this link button to      ' send its events to a different control.
     ' NOTE: the current ID is extracted from the current data row (ds) and added as the event argument to be sent with the post back                 lnk.Attributes.Add("href", "javascript:" + 
Page.GetPostBackEventReference(lnkRemoveEvent, ds("id").ToString()))
            End If
        End If
End Sub

Passing Command Arguments

In the previous code snippet showed the GetPostBackEventReference function. This function sets the current data row’s link button to send its events to a different control. The second parameter (the current items id) is sent as its argument. When using this technique, I have noticed that the argument isn’t passed properly all the way through the stack. By the time the
Command event fires for the stray link button, the command argument will be set to it’s default value every time, thereby loosing the ID of the data item in question. It is actually being sent, but is getting crossed up somewhere along the way. A quick fix for this is to grab the event argument that is passed from the form during the Page_Load phase. Once this is set, the event can get the current id from the global variable.

Dim last_event_arg As String

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles MyBase.Load
        ' Extract the event arg from the form and put it in the global 
variable.
        last_event_arg = Request("__EVENTARGUMENT")
End Sub

Pretty simple eh? Now you have the best of both worlds, a small view state and working, paging, sorting datagrid. The nice thing here is that you get to take advantage of the ease of the datagrid with its viewstate on, and keep your viewstate size down. Using this template, you can build the same features for about the same amount of work and get a much more efficient component.

Ray Pulsipher

Owner

Computer Magic And Software Design

PHP Tutorial – Lesson 2 HTML Vs. PHP

December 15th, 2005

Time for the second session of our PHP Programming Tutorial. This time around, I am going to attempt to explain the differences between what PHP does, and what HTML does. For many, the line between static web content (HTML) and dynamic web content (HTML mixed with PHP) is fuzzy.

1) HTML is for display ONLY!!!
2) PHP is for CODE ONLY… NO DISPLAY!!!

The GUI (Graphical User Interface) for a PHP app IS HTML! Without this, PHP would be nothing but a nice console. Lets illustrate this with a simple PHP script.



<?php
print "PHP Rocks!!!";
?>
<BR>
<B>HTML is cool too!!!</B>

The <B> tags around the HTML phrase makes it look pretty. Take those away and all you are left with is the text. If your PHP Print statements added some <B> tags around the statement “PHP Rocks!!!” it would make it bold. Not because PHP had anything to do with it, but because the web browser would recognize those tags and render the text accordingly:

 <?php
print "<B>PHP Rocks!!!</B>";
?>

Remember, PHP makes it work, HTML makes it pretty!

Lastly, I want to mention the difference between HTML in a PHP section (inside the PHP tags) and HTML outside a PHP section. When you open a PHP tag, the PHP parser expects ALL statements it encounters to be valid PHP code. HTML is NOT PHP and the PHP engine does not understand it. Any and ALL data (data is anything that isn’t PHP code) should be enclosed in the “s. Failure to do so will result in errors. Try leaving off a quote, or putting the “<B> tags outside the ” and see what happens.

It is very common for PHP to output HTML to help beautify the results and you should familiarize yourself with this process if you want to be a successful web developer.

Ray Pulsipher

Owner

Computer Magic And Software Design

PHP Tutorial – Lession 1 What is programming?

December 13th, 2005

Good Morning,
Learning to write software is tough. Not because it is actually hard, but because it requires LOTS of patience and time. More than many people are willing to spend. Aditionally, programming works like math, you can’t learn by watching, you need to get your hands dirty!

Lets talk about the components of a program. When you write software, you simply tell the computer what to do. The hard part is that the computer takes you so literally. Imagine trying to tell a two year old to take a bath. If you tell them, they might turn on the water, but never plug the tub. They may fill the tub, but never take off their clothes. They may even forget to use soap or get in. You have to be very specific with them and guide them through the process. Computers are the same way, but with out the cute that is generally present with a young child. In that case, its probly more like trying to talk Forest Gump through the process of disarming a nuclear bomb over the phone. It isn’t pretty, but it can be done if you can step outside your own little world and think they way he does.

Some of the parts that make up a program are:

  • Variables – These are just places to hold information like your name or age. These are temporary locations in that they exist in memory and not on your hard drive so if the program ends or the computer is shut off, this information will go away. We use them because they are FAST when compaired to a hard drive.
  • Functions and/or Subroutines – Think about a mathmatical function like F(x). You simply pass in a value, and it returns an answer. In programming, functions work the same way, only they don’t have to be mathmatical. This allows you to write function once (e.g. to calculate the square root) and use it in multiple places without having to re-write the code each time.
    Subroutines are like functions except that they don’t return an answer.
  • Classes and Objects – OOP (Object Oriented Programming) is a great tool that allows programmers to write reusable code and simplify an applications interface. We will get into this more later. It is VERY usefull and when used correctly, can reduce the number of bugs, lines of code, and even make a program more efficient (when used correctly!).
  • I/O – Input Output. Every program needs to gather information (from the keyboard, form a file, from the network) and then output its answers in a usable way (computer screen, network, to a file). Most applications today use a GUI (Graphical User Interface). This GUI helps aid the programmer in presenting a uniform and easy to use interface for the user. This is one type of I/O system. Another type is to create a config file where the application can read this information and know how to react accordingly (start -> run -> win.ini -> click ok). Along with this you could have an output file that would hold the results. There are many combinations and options available to mix and match. One option we will work heavily with will be databases.
  • Thats a good start. Lets try an actual program. Because we are using PHP, you will need a server setup where you can upload PHP scripts. The PHP scripts actually run on a server and if viewed locally will just show a text file full of code. If you need web space, you can contact me for prices.
    Here is the actual program…

    
    
    <?php print "PHP Rocks!!!"; ?>

    This snippet of code should output “PHP Rocks!!!” to your browser window if it works correctly. If you see the whole file (including the php tags) then your server isn’t executing the PHP code correctly. The cool thing about PHP is that ONLY THE OUTPUT goes to the web browser keeping your code safe!
    Lets break this down a bit. The first line (the php tag) tells PHP that actual code follows. This allows you to put PHP code into an HTML file without anyone getting confused as to where HTML stops and PHP starts.

    The last line (the closing php tag or ?>) is the signal that the stuff after this should be treated like HTML again.

    The middle line calls the print function which simply sends the specified output to the screen (or web browser in this case). The ; at the end tells PHP that this line is done. Give it a try. Your assignment is to save that as a file called hw.php and put it on a server, then send me a URL where I can navigate and see your handy work.

    Ray Pulsipher

    Owner

    Computer Magic And Software Design

    More enhacements to wp-mail.php

    December 13th, 2005

    Well, its time to start another day. Your day can’t be all bad if you can add some features to a product before work begins. How about some new enhancements to the wp-mail.php file in the wordpress software? One feature that was missing was the ability to specify a category for your e-mailed post to find its way into. Currently there is just one global category setting, and all email posts find their way there. I didn’t like this, so I added the ability to put Name/Value pairs into an email. The pairs currently available are Category and Post Status. Category can be any category in the system while Post Status can be Draft, Publish, or Private (as defined buy WordPress. All name/value pairs can be entered like this.

    Name:Value

    You should be able to add these anywhere in the message, but I would suggest putting them at the top.

    Additionally a few more bugs have been fixed (you can now put ‘ characters in your subject line). To download a copy of the current revisions, use the same link as before (https://www.cmagic.biz/wordpress/wp-mail.zip).
    How does it work? Well, its actually quite simple. After we have extracted the message body, we can process it a bit before too much else is done. At this point we can ask to retreive values from the body by using the GetPostValue function. This will scan the body looking for the specified name/value pair, and extract them from the body (it actually takes that line out so it won’t show up in the post). Using this, we can add as many options to the script as WordPress allows. I’ve done enough for the last few days on this, if some one wants to pick it up from here, go for it. The link above is a zipped copy of the current wp-mail.php file. Kindly send me a note letting me know if the changes were usefull though.

    Ray Pulsipher

    Owner

    Computer Magic And Software Design


    Home | My Blog | Products | Edumed | About Us | Portfolio | Services | Location | Contact Us | Embedded Python | College Courses | Quick Scan | Web Spy | EZ Auction | Web Hosting
    This page has been viewed 871056 times.

    Copyright © 2005 Computer Magic And Software Design
    (360) 417-6844
    computermagic@hotmail.com
    computer magic