DennyDotNet

Awesome ASP.NET C# and other cool coding stuff

About the author

Denny Ferrassoli
Developer at Casting Networks. MCP / .NET
E-mail me Send mail
Add to Technorati Favorites

Recent posts

Recent comments

Authors

Categories

None


Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

ASP.NET AJAX History and ASP.NET Hacks

I was running through my list of blogs and I ran into "Create a Facebook-like Ajax Image Gallery!" by John Katsiotis. In John's post he shows how to create an image gallery - it's quick and easy - but more importantly he utilizes the new ASP.NET AJAX History feature. That means you can use the back and forward buttons on your browser to go back and forward through the AJAX calls.

And on another note, LessThanDot has published a collection of ASP.NET Hacks in 18 categories (currently) including: Caching, Email, Encryption, Validation, Files and others.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: ,
Posted by Denny on Monday, July 07, 2008 3:52 AM
Permalink | Comments (0) | Post RSSRSS comment feed

.NET Framework Source Released

Back in the saddle!! Scott Guthrie has just let us know that the source code for the .NET Framework libraries, mentioned below, are available for browsing and debugging!

The libraries include:

  • .NET Base Class Libraries (including System, System.CodeDom, System.Collections, System.ComponentModel, System.Diagnostics, System.Drawing, System.Globalization, System.IO, System.Net, System.Reflection, System.Runtime, System.Security, System.Text, System.Threading, etc).
  • ASP.NET (System.Web, System.Web.Extensions)
  • Windows Forms (System.Windows.Forms)
  • Windows Presentation Foundation (System.Windows)
  • ADO.NET and XML (System.Data and System.Xml)

Instructions on installing the libraries for Visual Studio 2008 are located here: Shawn Burke's blog post. Read Scott Gu's post if you want to get the low-down.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by Denny on Wednesday, January 16, 2008 1:36 PM
Permalink | Comments (0) | Post RSSRSS comment feed

SoCal Code Camp!

Just finished RSVP'ing for SoCal Code Camp! It will be held on Jan. 26 and 27 at the University of California Fullerton (UCF). Head over to the website (below) and sign up! Hope to see you there!

From the email:

If you haven't already registered at http://www.socalcodecamp.com for the upcoming Rock & Roll Code Camp to be held in Fullerton - why not take a minute to do it now!?!?

We already have 50 sessions and counting. Many of your favorite speakers are returning to provide you with great new content including Kevin McNeish, Paul Sheriff, Daniel Egan, Michele Leroux Bustamante, Mickey Williams, Woody Pewitt, David McCarter and more! Imagine, many of these internationally known speakers frequent conferences like Tech Ed, PDC, MIX, Dev Connections, VSLive and more! And you get to see them talk for FREE!!!!

There are also some budding new speakers that offer great sessions based on their real world experiences in the local community. You could even be one of them - feel free to add more sessions to the site, we have room for more!

The schedule will be posted one week before Code Camp so you can plan your attack!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by Denny on Wednesday, January 16, 2008 5:44 AM
Permalink | Comments (0) | Post RSSRSS comment feed

The ASP.NET MVC Framework...

Finally some great news! Scott Gu officialy announced the ASP.NET MVC Framework on his blog. I'm so anxious to get my hands on the framework! If you're not familiar with MVC I would suggest reading Scott's post, he explains it briefly.

However there are some really cool features... for example you can use both MVC and WebForm frameworks. You can also continue to use Master Pages, ASCX controls, <%=%> snippets and plenty more. The MVC framework will not use the existing post-back model, instead you route all end-user interaction to a Controller (no viewstate or page lifecycle - a great approach).

What about ASP.NET AJAX UpdatePanels? Scott mentions this in his comments:

UpdatePanel does use postback, so you won't use that control directly within a MVC based view.  But there will be a control (and optional helper method) with capabilities very similar to it.  It will invoke an action on a controller and allow you to incrementally update a portion of HTML really easily.  It will enable you to use the ASP.NET AJAX libraries really easily.

Curious to see the "optional helper method."

My biggest frustration has been with the difficulty in mashing JavaScript with ASP.NET WebForm's rendered output. With the MVC Framework it seems like I'll finally have the control I want to use JavaScript frameworks and server-side controls seamlessly.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: , ,
Posted by Denny on Monday, October 15, 2007 3:35 AM
Permalink | Comments (2) | Post RSSRSS comment feed

SubSonic QueryCommand Object

The QueryCommand object in SubSonic makes writing SQL Commands a whole lot easier and less time consuming. When would you use it? Well sometimes the Query object can't perform complex queries, especially ones involving JOINS. So the QueryCommand is an excellent object to use when you need to run a complex query. Below is an example:


// The SQL (notice I am using parameters: @projectid)
string cmd1 = "SELECT ListName FROM tList a INNER JOIN tMain b ON b.tId = a.tId WHERE a.tId = @projectid";

// The QueryCommand object...
// SubSonic knows which connection to use based on the provider name “Master” which is defined in Web.Config
// Or leave it blank if you have a default provider selected (also defined in Web.Config)
QueryCommand q = new QueryCommand( cmd1, "Master" );

// Set the parameter(s)
q.AddParameter( "projectid", intProjectId, DbType.Int32, ParameterDirection.Input );

// Execute the command
string strValue = Convert.ToString( DataService.ExecuteScalar( q ) );

// You use the DataService object to execute your QueryCommand object.
// There are several methods you can use with the DataService object including:
//
// DataService.ExecuteQuery(...);
// DataService.ExecuteTransaction(...);
// DataService.GetDataSet(...);
// DataService.GetReader(...);

So in 4 lines of code (subtracting comments and breaks) you can run a custom SQL command. Thanks SubSonic!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by Denny on Thursday, October 04, 2007 6:43 AM
Permalink | Comments (1) | Post RSSRSS comment feed

A DataTable Serializer for ASP.NET AJAX

A DataTable Serializer for ASP.NET AJAX, implements JavaScriptConverter. Note that I did not implement a Deserialize method since I am using this for read only data.


/// <summary>
/// DataTable to JSON converter
/// </summary>
public class JavaScriptDataTableConverter : JavaScriptConverter {
 public override object Deserialize( IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer ) {
  throw new NotImplementedException( "Deserialize is not implemented." );
 }

 public override IDictionary<string, object> Serialize( object obj, JavaScriptSerializer serializer ) {
  DataTable dt = obj as DataTable;
  Dictionary<string, object> result = new Dictionary<string, object>();

  if( dt != null && dt.Rows.Count > 0 ) {
   // List for row values
   List<object> rowValues = new List<object>();

   foreach( DataRow dr in dt.Rows ) {
    // Dictionary for col name / col value
    Dictionary<string, object> colValues = new Dictionary<string, object>();

    foreach( DataColumn dc in dt.Columns ) {
     colValues.Add( dc.ColumnName, // col name
      ( string.Empty == dr[dc].ToString() ) ? null : dr[dc] ); // col value
    }

    // Add values to row
    rowValues.Add( colValues );
   }

   // Add rows to serialized object
   result["rows"] = rowValues;
  }

  return result;
 }

 public override IEnumerable<Type> SupportedTypes {
  //Define the DataTable as a supported type.
  get {
   return new System.Collections.ObjectModel.ReadOnlyCollection<Type>(
    new List<Type>(
     new Type[] { typeof( DataTable ) }
    )
   );
  }
 }
}

And how do you implement this? In a web service...


using System.Web.Script.Serialization;

// ...

[WebMethod()]
[ScriptMethod( ResponseFormat = ResponseFormat.Json )]
public string TestJS( int Id ) {
 JavaScriptSerializer toJSON = new JavaScriptSerializer();
 toJSON.RegisterConverters( new JavaScriptConverter[] { new JavaScriptDataTableConverter() } );

 DataTable dt = new Query( Log.Schema )
   .WHERE( Log.Columns.ID, Id )
   .ExecuteDataSet().Tables[0];

 return toJSON.Serialize( dt );
}

That's all there is to it! Just deserialize to an object on the client-side and you're good to go!

Side Note: There is a DataTable serializer from Microsoft in the ASP.NET Futures package.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags: ,
Posted by Denny on Friday, September 14, 2007 11:05 AM
Permalink | Comments (2) | Post RSSRSS comment feed

UpdatePanels: When and Where

I've been using the ASP.NET AJAX Update Panels for quite some time now and have picked up a lot of tips on when and how to use them. Update Panels were intended to allow the developer to do Partial Page Updates. Usually what you see is Update Panels updating nearly the entire page which completely defeats the purpose of Update Panels!

Here are some good tips to take into account when developing with Update Panels:

#1. One thing I notice is that people want to stuff all their functionality into one page with multiple hidden/visible panels. Then utilize the functionality by showing/hiding the panels based on actions within the page. This can lead to very confusing code...

If you're changing from one action which does a lot of functionality with X to an action which does a lot of functionality with Y then separate the functionality and use a page postback to switch between those pages. Don't throw everything together into one update panel and separate it by hidden panels. You'll end up with a ton of code which is not resuable and difficult to understand. Separate your functionality just like you would separate your DAL, BL and Presentation.

Example for an Admin section:
  • User Management (insert, update, delete users)
  • Settings (change your web app's settings)
  • Media Management (insert, update, delete media)
  • etc...

#2. Separate your Update Panels. Instead of throwing everything into one update panel break it up! Plan what areas of your page will need to update and what will trigger them to update. This will save you an insane amount of bandwidth (and download time) and return much better performance.

Example:
Lets say you have 3 areas on your page that will allow a user to: select a category, select a video and then watch the video.

  • Part 1 displays a list of categories
  • Part 2 displays a list of videos within that category
  • Part 3 displays a video player

Lets think logically about the flow of execution with the 3 parts. First a user picks a category in Part 1. Then they select which video they want to watch in Part 2. And finally the video displays in Part 3 and begins playing.

So there are 2 steps involved to watch a video:

  1. Pick a category
  2. Pick a video


And 2 triggers:

  1. "Click" a category
  2. "Click" a video



(Each arrow represents a click)

So we've got the basic idea down now how do we determine WHERE we need update panels? We need to determine what parts change. The only parts that change are Part 2 which shows a list of videos within the selected category and Part 3 which plays the selected video. Part 1 will not change because nothing within that part changes. Part 1 is only used to select a category and the categories are loaded at Page_Load.

(Of course if you added paging or sorting to Part 1 you could then use an update panel but for this example Categories are static.)

So you have 2 parts that change meaning you only need 2 update panels, one for Part 2 and one for Part 3. Now how do we trigger these updates? Based on the flow we determined above we know what triggers are needed...

Triggers:

  • Part 2 needs to update when a category is selected from Part 1.
  • Part 3 should update when a video is selected from Part 2.

We also want to hide the video player when the user selects a new category because it wouldn't make sense to continue showing a video from the "Comedy" category after they selected the "Drama" category. So we'll need one more trigger:

  • Part 3 should update when a category has been selected since we don't want to display the old video when they select a new category.


(Each arrow represents where the item is triggered from [start of line inside part] and what part it affects [end of line])

And that's all we need to properly separate our update panels. The cool thing about upate panels is that your trigger control does not need to be within the same update panel. In other words, it can be located anywhere on your page outside the update panel. That's why we only need 2 update panels. The triggers in part 1 can be set programatically or through the update panel "triggers" GUI from the properties menu.

Quick Tip: If you want to know how to set a trigger programatically then read this post.

What's the benefit of separating the update panels? Alot of Bandwidth! Update panels respond with their entire rendered contents when doing an AJAX call. Update panels also attach any control viewstates to the response. If you were to place the entire content of the example above in one update panel you'll be uploading and downloading everything every time you do a callback. On the other hand if you separate your update panels, like the example above, you'll only download the contents of the update panel that has been triggered.

Quick Tip: If a control within an update panel does not need viewstate enabled then disable it! This is a good way to decrease the size of the response.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by SuperGhost on Thursday, August 30, 2007 9:19 AM
Permalink | Comments (1) | Post RSSRSS comment feed