Injecting javascript into asp.net via code

Microsoft has a great MSDN article on using javascript along asp.net, but they didn’t mention a technique I like to use, put it in a Literal control.  While there are many ways to add javascript to a page, I find putting the javascript in a literal much less stressful. Using a Literal control placeholder is also a good way to add messaging to a page after postback, but we’re just going to look at adding javascript.

Let’s take a simple example.  Say you’ve got a comment form that you want to auto close, or reload after the form was posted.  Below is a simple single file style asp.net page with a simple javascript function that reloads this page.

<%@ Page Language="C#" %>

<script runat="server">
/// <summary>
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {

    }
}

/////////////////////////////////////////////////////////////////////////////// 
/// Do stuff with the form data, then refresh page using javascript
protected void submitComments(object sender, EventArgs e)
{

    try
    {
	//
	// do stuff here
	//

	// set javascript timer to reload page afer 3 seconds
	js_target.Text = "setTimeout('reload()', 3000);";

    }
    catch (Exception exc)
    {
        Response.Write( "ERROR : " + exc.Message );
    }
}
</script>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
	<title>Comments</title>
	<script type="text/javascript">
	// page reload helper
	function reload() {
		document.location.replace( document.location );
	}
	</script>
</head>
<body>

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

<script type="text/javascript"><asp:Literal runat="server" id="js_target" /></script>

	Comments
	<asp:TextBox runat="server" ID="comment_box" Width="200" />
	<br><br>

	Your name
	<asp:TextBox runat="server" ID="fullname" Width="200" />
	<br><br>
	<asp:Button runat="server" ID="submit_btn" onclick="submitComment" Text="submit" />

</form>
</body>
</html>

If you look just under the form tag you’ll see the key to this technique, an asp literal wrapped by an open and close script tag.

<script type="text/javascript"><asp:Literal runat="server" id="js_target" /></script>

When you load your page and view the source you’ll just see an empty script tag, so it shouldn’t interfere with the execution or rendering of your page.

The last part of this technique is simple, in your server code just set your Literal control’s .Text value to your javascript code. In this case when I post my comment form, after handling the input data I display a thank you message, then set some javascript to reload the page.

ltl_js.Text = "setTimeout('reload()', 3000);";

That’s all there is to it. Drop a literal in an empty script block and BAM!, you have an easy way to add javascript to your asp.net page.

Endless Mural wins FWA site of the day

FWA Site of the day > Nov 22 2010

Endless Mural wins FWA for HTML5

I’m ecstatic to announce the Endless Mural HTML5 project has won the prestigious FWA Site of the day award.  While this isn’t the first project I’ve worked on that has won the FWA, it is the first NON-Flash, HTML5 and ASP.NET project that has.  No Flash, and we still got the FWA site of the day, SWEET!.

I need a SQL Ninja

On Friday July 23rd I got the chance to skateboard with my good buddy and personal hero Joshua Davis. I feel lucky being able to say we’ve actually been skating together for a few years now, but this was certainly my favorite session we’ve had so far. We started out at Broomfield’s new park because I had to show Josh the new mini bowl.

skate or fry

Two hot dogs ( http://yfrog.com/n3hs5j )

After Broomfield we made a quick stop for lunch, and then on to the Denver Skatepark in downtown.  It was great showing Josh the lines at my hometown skateparks, as well as a few radical maneuvers.

Now that Josh had seen my non-frontside airs, it was time to wrap things up.  As we were saying our goodbyes I decided to ask about work.  Normally I don’t talk about work at the skatepark, but I was thinking about going indie again, and figured what the heck.

Turns out Josh was about to start a project for Microsoft ( WHAT?!?! ) and he need to “find a SQL Ninja” ( DOUBLE WHAT?!?! ).  I’ve been actively working with MS SQL Server since version 6.5, so I let him know he was looking at his sql ninja.  Josh was interested, but gave me the “just cause we’re bros, doesn’t put you on the team”.

HTML5 drawing tool in one night

Driving home from the skatepark I called my wife super giddy.  “Honey, I may be going indie sooner than we planned”.  I gave her the rundown of the potential project Josh and I just spoke about, and let her know I had some homework to do.  That night I went home and built out a distant cousin of the endless mural project.

You can draw with HTML5

HTML5 drawing tool powered by ASPX and MySQL

sloppy html5 drawing

HTML5 drawing tool powered by ASPX and MySQL

EFDRAW is a really simple HTML5 drawing tool powered by ASP.NET and MySQL. It has most of the features of the mural ( draw, save, replay, share ), but this was only a proof of concept.  This was my first dive into HTML5 development, and it’s pretty sweet.

http://www.screentoaster.com/swf/STPlayer.swf

If you’re interested in HTML5 drawing tools, feel free to play around with EFDRAW, view source, help yourself.

There’s one thing…. Azure

A few days after building EFDRAW my band The Compilers played at Ignite Denver 7. Right before starting our first set my phone rings and it’s Josh! OMG I think, this is either the “you got it” or the “sorry bud, we’ll skate again” call. I decide to take the call even though we were locked and loaded, standing on stage with our gear waiting for the house music to go down. I answer and it’s Josh, but not the usual hyperactive Josh I’m accustomed to. I ask about the gig and he says “Well, there’s one thing. We have to use Azure”.

I let him know I’ve worked with other cloud platforms already, just not Microsoft’s. So we talk a little more and Josh passes the phone to Branden so we can talk 0s and 1s. After talking to Branden “mega brain” Hall for a few minutes he asks if I can do this. I tell him yes, he says yes, I get excited, he gets excited. Branden passed me back to Josh and I’m in shock at this point.

Now the boring stuff

So that’s the story of how I landed the Endless Mural gig, now the boring technical details.

The drawing portion of the mural was built by Branden Hall of Automata Studios.  I did the backend which is made up of ASP.NET ( C# ), SQL Azure, and Windows Azure.  We’re using Azure blob storage to save and serve up the PNGs created at the mural.  To access SQL server, I wrote a super lightweight data access library using all native .NET.

For the most part the backend was very much like every other .NET SQL Server project I build, but Azure did introduce a few gotchas.

  1. The publishing and management of your cloud site mainly goes through http://windows.azure.com/.
  2. You can deploy your site from Visual Studio which proved to be immensely helpful after my Azure deploy package grew beyond 100 MB.
  3. You can access SQL Azure directly from SQL 2008+ management tools.
  4. You can not FTP single files up to the cloud, only the full ball of wax.
  5. You can still use web.config for configuration storage, but Azure also has it’s own version of web.config.
  6. If you need to edit your settings after deploying, store those settings in your Azure service config, not web.config
  7. SQL Azure requires all tables to use clustered indexes
  8. SQL Azure has it’s own TSQL restrictions ( not many, but be aware )
  9. On average, doing a full republish of an Azure site took a full hour.

I could probably ramble on and on about Azure, but I’ll cut it short.  If you happen to have any questions about Azure feel free to hit me up or leave a comment.  I would also like to say that I know Microsoft is and has been actively improving Azure by the day.  The state of Azure today is most likely even better than when we built the mural, so my experiences may not be your own.

The toolbox

  • Windows Azure SDK
  • Windows Azure Platform Kit June 2010
  • Windows Azure Tools for Visual Studio ( v1.2 )
  • Microsoft Seadragon Ajax library
  • Microsoft SQL Server 2008 R2
  • Microsoft SQL Azure
  • ASP.NET 4 ( C# )
  • Windows Azure
  • Azure Storage Explorer

Here is the toolbox that Branden used on the client side.

Hotlinks from the server guy

It’s a wrap

This project was the most concentrated five weeks I’ve had in quite some time. I still wonder if we were only given five weeks because this was an HTML5 project. Either way, the mural team made some magic and now you can too. If you’re like me and just want to doodle, go make some art at the mural. If you’re a developer interested in HTML5 and Javascript programming, go check out the javascript library okapi.js which Branden Hall recently open sourced.

Also be sure to visit the magicians, I mean artists, who made the amazing patterns you see when using the mural. I’m a life long doodler, but can’t art myself out of a paper bag.

Guilherme Marconi

Guilherme Marconi - brain.marconi.nu

Guilherme Marconi - brain.marconi.nu

Matt Lyon

And lastly I put up a photo album on Facebook of all my camera phone pictures from the trip.  Check out the endlessmural photo album.

Want to see some kick ass HTML5?

I’m extremely happy to announce the www.endlessmural.com project was launched today and it was a huge success.  I intend on posting something with more details when I return home, but in the meantime please please check this site out.  It’s my current favorite example of HTML5 in action, and it works in all modern browsers ( yes, even iPad ).

The coolest HTML5 sample you will see on the internet

Go make art at endlessmural.com

Endlessmural.com is a generative drawing tool written in HTML5, Javascript, CSS3, on top of a Microsoft Azure backend.  Go, make art, share the url.

Here is a piece I made today.

endlessmural.com artwork

DataBind a List of custom classes to an ASP:ListBox control

Recently I was scratching my head at this error from the .NET Framework

DataBinding: ‘MyApp.vo.customVO’ does not contain a property with the name ‘Name’

I was stumped because my custom VO class did in fact have a public property called Name.  After many trials and tribulations I figured out that .NET didn’t like how I structured my custom class.

Here is what my original custom class looked like.

namespace MyApp.vo
{
    public class customVO
    {
        public Int32 id  = 0;
        public DateTime time  = new DateTime();
        public string Name  = string.Empty;
        public string DeviceType  = string.Empty;
        public string ObjectIDs  = string.Empty;
    }
}

Luckily I have JetBrains ReSharper installed, and it suggested using C#’s Auto-Implemented properties. This is the one thing I hadn’t thought about trying, and it ended up being the fix! My new custom VO class now looks like this.

namespace MyApp.vo
{
    public class customVO
    {
        public Int32 id { get; set; }
        public DateTime time { get; set; }
        public string DeviceType { get; set; }
        public string ObjectIDs { get; set; }
        public string Name { get; set; }
    }
}

So if you find yourself running into this error while trying to DataBind a collection of custom classes to a ListBox or similar control, have a look at your custom class and see if you can convert it over to using auto-implement properties as well.

Now I’m not suggesting this is the only way to DataBind a List of custom classes to a ListBox, but it solved my problem and let me do direct databinding from my service call without having to do any pre-processing on my list.

Hope this helps someone else.

Coldfusion and ASP.NET coexisting on IIS, where’d WebResource.axd go?

My Monday morning WTF comes from IIS7 on Windows 7.  I recently installed Coldfusion9 on this machine which has a handful of existing ASP.NET 3.5 web applications.  The problem I ran into came after installing Coldfusion9 and electing to configure all IIS websites to work with CF.  While that is convenient, it ended up breaking one of my ASP.NET applications that was using ASP Validation controls on a login form.  Now that things are figured out, here are the details.

Firing up my ASP.NET application gives me the error message :

The WebResource.axd handler must be registered in the configuration to process this request

Misleading web handler error message

WebResource.axd handler must be registered

Obviously all I could think is WTF?!?!? since this application worked on Friday and now it is broken.  The first thing I want to point out is that in my situation, the suggested solution of mapping WebResource.axd in the httpHandlers section of my web.config did not help this problem.  After some googling I cam across this post on the IIS.NET forums which put me on the right track.  You can read the details there if you want a good background on MS’ response and other users running CF and ASP.NET on the same box.

I’m happy to say I have three workarounds for this issue.  Hopefully these will help you as well.

1. Change your AppPool to run in Classic Mode

  1. In inetmgr, put your web application into it’s own Application Pool ( unless it’s already in it’s own pool )
  2. Change that AppPool’s Managed pipeline mode to “Classic”
  3. You should be good to go
Change Managed Pipeline Mode to Classic

Classic mode is for compatibility ( think IIS6 )

2. Stop using ASP Validation controls

All ASP.NET Validation controls are hosted by WebResource.axd.  If you stop using ASP Validator controls, the server will stop asking for WebResource.axd.

Comment out ASP Validator controls

Removing ASP Validator controls should remove this error

3. Remove Coldfusion handler mappings from your ASP.NET site

If your ASP.NET app isn’t using Coldfusion, I would suggest doing this as your solution.  Even if you do need Coldfusion in your ASP.NET app, you could still host your CF app in it’s own Virtual Directory and request if via ASP.NET.

  1. Open inetmgr
  2. Select your web app on the left ( under Default Web Site )
  3. In Features View on the right, double click Handler Mappings
  4. Sort your Handler Mappings by Name, and remove all entries titled “AboMapperCustom-*”
  5. Now your ASP.NET should work like a champ.
IIS7 inetmgr Handler Mappings

IIS7 Handler Mappings

Coldfusion9 Handler Mappings

Coldfusion9 Handler Mappings

Monday WTF solved.  Now to get back to pushing buttons.

How to JOIN two tables using LINQ to SQL

Wanted to share this since it gave me so much trouble figuring out.  It’s a simple SQL query ported to LINQ to SQL that joins two tables to return a filtered listed of data.

Here are the tables from my schema
user, user_video, video tables

Here is a basic SQL statement I could fire to retrieve my user videos.

select  *
from    video v, user_videos uv
where   v.vid = uv.vid
and     uv.uid = 2

User 2 has two videos
Here is how you would run the same query using .net’s LINQ to SQL.

// create DB connection
var db = new DBCONN();
// run query
List<video> uvids = (
    from c in db.video
    join o in db.user_videos
    on c.vid equals o.vid
    where o.uid == 2
    select c
).ToList();

This query differs slightly from the screenshot below because I used it in a WCF Service.

Same data, different retrieval method

The variable DBCONN is my database connection that I established when mapping my DB.  If you are not familiar with how to set this up, use the Visual Studio’s “Add the ADO.NET Entity Data Model” wizard.  With your .net project open, right click your project, left click on “Add the ADO.NET Entity Data Model”.  This wizard will walk you through setting up everything you need to setup your DB model file ( edmx ), as well as setting up your database connection and saving it in web.config.

Jesse Liberty did a simple tutorial that uses this wizard in a WCF service application.

I hope this helps somebody out.

Create a delimited list of SortedList Keys in C#

I love C#, but miss the simplicity of PHP sometimes.  Specifically when dealing with collections.  Recently I ran into a situation where PHP’s implode would have been perfect, but I wasn’t able to find any quick and easy built in solution.

I would like to be able to do this

[csharp]
string id_list = implode( ",", mySortedList.Keys );
[/csharp]

I’m not aware of any built in ways to do this, so I wrote the following helper function.

[csharp]
///
/// Pass in a SortedList and this will return a string containing a delimited
/// list of keys separated by delim
///
///

///

/// key1{DELIM}key2{DELIM}keyN
public static string SortedListKeysToDelimList(SortedList sl, string delim)
{
StringBuilder sb_keys = new StringBuilder();

foreach (DictionaryEntry dl in sl)
{
sb_keys.Append( dl.Key.ToString() );

// append DELIM only if we’re NOT on the last entry
if (dl.Key != sl.GetKey(sl.Keys.Count – 1))
{
sb_keys.Append( delim );
}
}

return sb_keys.ToString();
}
[/csharp]

If there is any better way to do this, please leave me a comment.