Hugoware

The product of a web developer with a little too much caffeine

Archive for July 2009

Getting Started With Silverlight

with 4 comments

Today I got started using Silverlight for the first time today. Presently, Silverlight is on version 3 so I’m a little late to the party (but then again given the speed of the releases, I may not be that far back after all). I was leery of using Silverlight because I’ve always liked working with Flash, mostly because I really like taking a break from statically typed languages and playing with dynamic languages.

However, Silverlight is just filled with pure awesome so far. .NET Framework, available from a RIA? Sweet!

I dont’ have as much to say today as usual because I’m still working on this project — but I can say that I’m really excited because a project I’ve wanted to build forever now is actually available for the first time thanks to the features found in Silverlight.

Over the next few months I’ll share my progress on my creation and hopefully get some feedback about what people think — but as for now, I’m still just trying to figure out how to move some rectangles around. ๐Ÿ™‚

Does anyone have any recommended resources for learning Silverlight? Especially creating games?

Written by hugoware

July 30, 2009 at 2:37 am

Include Stylesheets and Scripts From A WebControl In MVC

with 8 comments

As of MVC2 this code may not work anymore – Check here for updated code.

Have you ever created a WebControl in MVC and though “Gee, it sure would be nice if I could add a stylesheet/script to the header of my page.” It’s not as easy as it used to be. Lets just pretend you ran this code right here.

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<html>
    <head runat="server">
        <title>Just A Test</title>
    </head>
    <body>
        <% Page.Header.Controls.Add(
            new LiteralControl(
                @"<script src=""/script.js"" type=""text/javascript"" ></script>"
                )); %>
    </body>
</html>

It would compile and run just fine but you wouldn’t see your script! That’s because the page life-cycle has come and gone and you’re in the middle of the page render! We’re too late!

Inline code doesn’t make it easy to communicate with other parts of the page. As far as I can tell, inline code is rendered in the same order that it appears on the page (or at least, parsed), so once you finally get to the end of the page, the code at the start has already been executed.

A Workable Solution

I’ve included some code at the end of this post that simplifies the whole process and for the remaining of this post I explain how it works. In an effort to solve this problem I ended up coming up with two extension methods that are attached to the HtmlHelper.

InsertMarker(id) : Creates a point on the page that will render any content that is added to it. Uses the id provided (either an enum or a string)

AppendToMarker(id, content) : Appends the string content to the matching marker id (either an enum or a string)

These methods allow marker points to be added to the page inline and then content appended to each marker, regardless of where they are used. Let’s look at an example of the code. If this code doesn’t make sense just yet, don’t worry — I’ll explain ๐Ÿ™‚

A Simple Example

Lets use this code to add a script to the header of our page — but from within a WebControl.

[Index.aspx (the View)]

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<html>
    <head runat="server">
        <title>Just A Test</title>
        <% this.Html.InsertMarker(Document.Head); %>
    </head>
    <body>
        <% this.Html.RenderPartial("SomeControl"); %>
    </body>
</html>

[SomeControl.ascx (the WebControl)]

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% this.Html.AppendToMarker(
    Document.Head,
    @"<script src=""/script.js"" type=""text/javascript"" ></script>"
    ); %>

As you can see, we can pick the name of the marker that we want to append content and it is added to the page — all from within our WebControl! You can define your own custom markers and append content to really anywhere you want on the page. If the marker isn’t found, then the content is never rendered.

How It Works (The Short Version)

Once we’re in the middle of our render event for our page it makes it quite difficult for us to make many changes to the rest of the document. This is where the HttpContext.Response.Filter stream comes in handy. With this stream we’re able to intercept all of the content before it is really sent out.

Each time we set a marker onto the page we place a bit of text to mark it as a point we need to replace before we push the content out. I had preferred the idea of remembering the position of the output stream, but apparently the output stream is written to all at once which took that out of the picture.

Once we’re done its as simple as using a Regular Expression and replacing all of the markers with the correct content.

MVC-ish – Kinda Sorta…

This may not have been what the guys who designed MVC were thinking of when they created it, but the ability to work with multiple areas of the page was definitely a feature that I felt was missing. How could something like this help you with your projects?

Source Code

ContentMarkerHtmlHelper.cs (Source)

.

Written by hugoware

July 28, 2009 at 1:57 am

Using WebControls In ASP.NET MVC Views – Part 1

with 4 comments

Check out my newest blog post about using WebControls inside of MVC (source code included)๐Ÿ™‚

WebControls In MVC Series

I always thought it would be interesting to be able to use WebControls within an MVC application. I’m sure that there is a lot of people that have invested a lot of time in developing custom WebControls that would hate to see them be thrown out just to use the newest framework from Microsoft.

If you think about it, using WebControls inside of MVC doesn’t seem to be that impossible of a goal. All we need to do it post back the ViewState and we’re good to go, right?

Well, as it turns out, it’s a little harder than I thought it might be. Over the next few weeks I’ll be discussing what I’ve tried and where I get. I’m really not even sure if it will end up working out, but here goes anyways.

Disclaimer: This post is the first in a series of experiments to see if bringing WebControls inline with MVC is even possible — the code in these posts do not work and are only for getting ideas and promoting discussion — basically, this code is crap. ๐Ÿ™‚

Rendering The Control

I blogged awhile back about using WebControls inside an MVC application, but it covered only controls that didn’t need to postback to the server. Not really that much help but interesting to say the least. The basic idea was to simply create an extension method that performed the DataBind and Render event on the control and then spit out the HTML output to the page.

Unfortunately, there is a lot more to a WebControl than just the rendered output. You’ve got the entire page lifecycle that isn’t being processed anymore, no page level forms with unique IDs, missing your ViewState, on and on… Not looking so great at the moment.

The Plan

Have you ever used the BuildManager class? Its probably not the most commonly used class in .NET, but it has some interesting potential for what we’re wanting to do.

Let’s say for a moment that in the render event of the page we create a second page to host our control, process the page life-cycle and then dump the rendered content back into our page. Granted that won’t work for all of our controls, it might give us a point to start from. By using the BuildManager class we can load an instance of our host page and then process the request all from a helper method in MVC.

The Setup

Let’s hack out a few bits of code to get started. First, lets make a page in our Views directory and make some changes to the code behind.

[ControlLoader.aspx.cs]

//snip...
namespace MvcTest.Views {
    
    public partial class ControlLoader : System.Web.UI.Page {

        //event to catch the formatted string
        public event Action<XDocument> ProcessOutput;

        //override the render event to send the string for processing
        protected override void Render(HtmlTextWriter writer) {
            XDocument document = null;
            using (StringWriter output = new StringWriter()) {
                using (HtmlTextWriter html = new HtmlTextWriter(output)) {
                    base.Render(html);
                    document = XDocument.Parse(output.ToString());
                }
            }
            this.ProcessOutput(document);
        }    

    }

}

[ControlLoader.aspx]

<%@ Page Language="C#" 
    AutoEventWireup="true" 
    CodeBehind="ControlLoader.aspx.cs" 
    Inherits="MvcTest.Views.ControlLoader" %>
<html>
    <head runat="server" />
    <body>
        <form id="pf" runat="server" />
    </body>
</html>

So basically, we’re creating a page class that is going to raise an event that contains the rendered code as a parsed XDocument. With our output we’re now able to insert the relevant code into our MVC page.

Now let’s look at the code for our helper method.

//snip...
namespace MvcTest {

    public static class RenderControlHelper {

        //renders a control and then attempts to perform the page
        //lifecycle using it ((WARNING: Doesn't work -- just experiment code))
        public static void RenderControl(this HtmlHelper helper, Control control) {

            //load our control loader page
            ControlLoader page = (ControlLoader)BuildManager.CreateInstanceFromVirtualPath(
                "~/Views/ControlLoader.aspx", 
                typeof(ControlLoader)
                );

            //add the control to the page
            page.Init += (sender, e) => {
                page.Form.Controls.Add(control);
            };

            //add our event to process the string after the render
            page.ProcessOutput += (output) => {

                //output any header stuff (trying to think of a better way)
                foreach (XElement element in 
                    output.XPathSelectElement("html/head").Elements()) {
                    HttpContext.Current.Response.Write(element.ToString());
                }

                //output any form stuff
                foreach (XElement element in 
                    output.XPathSelectElement("html/body/form").Elements()) {
                    HttpContext.Current.Response.Write(element.ToString());
                }

            };

            //setup a separate context (maybe)
            HttpContext context = new HttpContext(
                HttpContext.Current.Request,
                HttpContext.Current.Response
                );

            //process this request separately
            ((IHttpHandler)page).ProcessRequest(context);
        
        }    
    
    }

}

Our helper method is clearly a little more complicated, but the basic idea is to load a instance of a second page, insert the control into the page, render it and then output our content inline. There is probably several mistakes in the code above that needs to be sorted out (for example, do I need to make a new HttpContext or just use the current one), but those can be worked on later. For now, this method does exactly what we’re wanting.

Let’s actually try this out with a simple TextBox.

[Index.aspx]

<%@ Page Language="C#" 
    MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="MvcTest.ViewStatePage" 
    AutoEventWireup="true"
    %>    
<%@ Import Namespace="MvcTest" %>

<script runat="server" >    
    TextBox box;

    //use this code to prepare our control
    void Page_Load(object sender, EventArgs args) {
        box = new TextBox();
        box.Load += (s, e) => {
            box.Text = "Some text";
        };
    }    
</script>

<asp:Content ContentPlaceHolderID="MainContent" runat="server">
    <form method="post" >
        <% this.Html.RenderControl(box); %>
    </form>
</asp:Content>

Okay, looks good – We want to see if our events are registering like we hoped so we add a Load event to add a value to the page. When we load the page we see the following…

webforms-1-1

Whoa! Am I seeing this correctly? Did it work? We look at the HTML that is generated and we see what we were hoping to see.

<!--snip-->
<form method="post" > 
        <title></title><div> 
  <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTcwNjgyNTAxMGRk6BLytKdG60ETSGMbSrNnJrnccfg=" /> 
</div><input name="ctl01" type="text" value="Some text" /><div> 
  <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgKeid+0CQKiwImNC/5nNKY1w+4g2ZcTRkCNUf9YR9ax" /> 
</div> 
    </form>
<!--snip-->

It’s ugly, but it’s what we we’re wanting to see — we can always come back later and do some cleanup. So what happens when we hit enter and post it back?

webforms-1-2

Ouch…

Back To The Drawing Board

I messed around with that error for a couple hours but couldn’t find anything that would make it go away. I tried turning off the ViewState encryption, hardcoding the encryption the keys, etc — no fix. I’m certainly not ready to give up on this idea, but for now it looks like I have to admit defeat. ๐Ÿ™‚

If I understand correctly you can run WebForms pages side by side with MVC pages, so I may be trying to solve a non-existent problem.

What do you think? Is this a waste of time? Does it solve anything? Is there an easier way?

Stay tuned for Part 2 — Coming soon!

Written by hugoware

July 27, 2009 at 12:05 am

Dude, For Real — Encrypt Your Web.Config

with 5 comments

After I released my web.config encryption utility I expected the world to transform into a Utopia of protected web.config files and happy developers. However, shortly after the tool was released I actually received some disagreement about the usefulness of web.config encryption.

Based on some other comments I received I got to thinking — I not sure that some people realize how possible it is to lose a web.config from a simple programming mistake.

But The Web.Config Is Safe — Right?

Sure, your web.config is safe by normal means. Just try it – find an ASP.NET website and just try to browse to their web.config file — See! it’s safe!!

True, your web.config is safe – but what about a programming mistake? Those never happen, do they? Are you sure?

One of my favorite examples is the file download. Sometimes we want to serve up content as if it is a download instead of showing it in the browser. That said, here is an ASP.NET MVC example of why you ought to go on ahead and encrypt that web.config file just to be on the safe side.

//MVC Action to download the correct file From our Content directory
public ActionResult GetFile(string name) {
    string path = this.Server.MapPath("~/Content/" + name);
    byte[] file = System.IO.File.ReadAllBytes(path);
    return this.File(file, "html/text");            
}

Seems reasonable enough – Other than error handling, do you see anything that looks out of place with this code? We map to the correct directory, we get the bytes for our file and return them to the visitor — You can even try it out.

/Home/GetFile?name=File.txt
bug-1

Cool, see how our file downloaded – Works great! But let’s be a little sneaky and play with the URL at the top. How about we do something like…

/Home/GetFile?name=../web.config

bug-2

Did you just get a sudden feeling of dread? Did you just shout ‘Oh Snap!’ loud enough that all your peers are staring at you? What do you suppose is in this file we just downloaded? I’ll give you three guesses, but I’m taking two of them away…

bug-3

It’s not hard to miss something — after all that’s why it’s a bug, because if we thought of it then it wouldn’t be there to begin with. Web.config encryption == cheap insurance.

Prying Eyes

I got this comment the other day and it was absolutely brilliant — Rob Thijssen wrote…

Encrypting configs in enterprise applications is definitely worth the time. Many companies allow contractors access to source code repositories that contain unencrypted configs that contain credentials which can be used to gain access to sensitive information. I have seen implementations where credentials were available to hundreds of developers that could give any one of them access to thousands of credit card details…

And he’s absolutely right. Do you want just anyone passing through the directory to have access to read the sensitive data inside your web.config? Just because they didn’t have hack into your server doesn’t mean they need to be reading the passwords to your SQL servers.

Dude, For Real — Just Do It

Web.config encryption only takes a couple moments and provides much more security than a clear-text file. It may not be enough to thwart a hacker that has full access to your entire server, but if you ever have that ‘uh oh — someone just downloaded my web.config’ moment, then at least you know you’re covered.

Written by hugoware

July 22, 2009 at 10:16 pm

More jQuery Magic – iPhone Style Password Box

with 2 comments

I like to think of myself as a technology-neutral developer that can look past any Microsoft-Apple rivalries and instead focus on the best tool for the job…

I like to think that — but I know that I’m a total Microsoft fanboy… ๐Ÿ™‚

So wouldn’t you know it that my entire FAMILY has been purchasing Apple stuff lately? Each (adult) family member has an iFail iPhone (except me, of course), my brother has an iTouch, sister-in-law with MacBook – Blasphemy! From my own flesh and blood!! ACK!!

However, despite this treachery I did discover that I did like the way that Apple handled inputting passwords.

iPhone Style Password Box

It’s worth mentioning up front that this code is just an experiment — it’s not a finished product and probably shouldn’t be pasted into a live site.

If you’ve used an iPhone before then you’ve probably noticed that you can see the last character you entered when inputting your password. This character disappears after a moment or two or the next time you enter a character. Using some jQuery and a hidden password field I attempted to create something similar.

[Sample version here.]

password-style-1

Now unfortunately, by using a div instead of an input I’ve taken away the ability to select the characters in the field. When I was working on this I had an idea that I might try using the ‘contenteditable’ property instead and then display the normal password box for browsers that don’t support it.

Why Not A Input[Type=Text]

I tried doing a similar idea with by using a regular text box and just masking the characters on the fly, but ran into a problem where pasting a password would cause the whole thing visible for a moment — which seems like too much of a risk.

Another Approach

The basic idea of the Apple style password box was to show the most recently entered character but the first example lost some of the usability of a normal password box. I figured I’d give the idea a second pass, but adjusted it to be a little more HTML friendly.

[Sample version here.]

password-style-2

You’ll notice in this version that the characters actually float up as you enter them. Similar to before, after a few moments, or when you press a new key, they will disappear.

This version is better from a usability standpoint, but it does have a couple problems of its own. For example, if you enter a really long password then the floating box stops moving at the end — no big deal right? Well for the end of the box, no, it looks fine — but if you click back out in the middle then your floating hints may be off-centered.

Simple But Effective Interface Designs

The code above isn’t ready for publishing, but they are some interesting examples of how you can take a typical form element and use a little jQuery to make some great usability enchancements to them.

You may have read some of my earlier jQuery posts about mimicking Vista style password boxes or creating search highlighting for web pages and noticed that it doesn’t take that much code to transform the functionality of your pages.

How do you enhance your pages for your visitors? It doesn’t take much!

Written by hugoware

July 22, 2009 at 6:24 am

Is Encrypting Your Web.config A Waste Of Time?

with 3 comments

In my last blog post I wrote about a utility has created to make it easier to encrypt web.config files hoping it would encourage more developers to protect their data. If you’ve ever tried doing it manually before, it isn’t really a very convenient process.

Additionally, I posted the blog entry on CodeProject — andย received rather interesting response.

This article is pointless.
– Quote any high security site that uses an encrypted config file!
– If somebody has physical access to your config file/web server, you are as well doomed

Really? Is encrypting your web.config pointless. I don’t think so. In fact, I replied back with the following.

Encrypting a web.config file isn’t to defend against your server being compromised, but even if it were then I don’t think you understand exactly how aspnet_regiis works. The keys are written and locked down so that only members of the Administrators group can even read it, any lesser privileged accounts still can’t decrypt your web.config. Since typically website worker processes are running as NETWORK SERVICE, then unless you did something REALLY silly, your web.config should still be safe.

Even though that isn’t bullet-proof security, think about this scenario — You’ve have some junior developer right out of college working on a project that allows people to go out and download documents off your web server. He wants to send back the file as a download so he writes the bytes to the response stream and makes a change to the content-disposition and viola – freshly served documents all with a nice and neat little download dialog box.

But if your developer left a tiny little bug in the app and it was possible to download “../web.config” — What would you prefer to be served up? Encrypted or unencrypted?

In my opinion, an encrypted web.config file is 100% better than no encryption at all. Logging onto the server and running aspnet_regiis was very inconvenient way to get this done – this tool was made just try and help people get it done without needing to invest a lot of time into it.

But this really got me wondering, is this really a common opinion in the development community? Is encrypting your web.config really a waste of time? I don’t really think that encrypting your web.config file is the solution to all your problems – but it is some really cheap insurance that you can take out on sensitive file.

So what do you think? Is encrypting a web.config worth the time?

Written by hugoware

July 20, 2009 at 6:28 am

Encrypt Your Web.config, Please

with 29 comments

If you follow me on Twitter you may notice me talk about #BadVendor from time to time. Actually, they were recently upgraded to #EpicFailVendor when I discovered they weren’t cleaning strings before passing them into SQL queries. Needless to say, everyday has been a little more shocking than the next.

For the most part all of these systems are things I can’t make changes to — either it’s compiled code or I just don’t have the authority to go in and make the fixes, but there is something that I can do — encrypt their web.config files.

Making Encrypting Easier

Encrypting normally involves logging onto the server in question, locating a few mildly obscure pieces of information and then running aspnet_regiis. It’s not that hard but it isn’t point and click easy as well.

I wanted to make it easier to update these files without needing to locate all the information each time so I wrote a little application to make the whole process a bit easier. The utility uses credentials you supply to log into your servers via WMI and locate the required information and then encrypt your files without needing to pull up a command prompt.

I’m not really a WinForms guy and WMI is certainly not my specialty, but this program came together pretty quickly and seems to be fairly decent. It’s certainly not bug free and could use a round of refactoring to make it nicer, so any feedback is appreciated.

How It Works

The first step is to provide your credentials to the server you want to log into. If you choose to run the tool on the actual server itself then you can leave all those fields blank (since WMI won’t use them for local connections anyways). If you aren’t an admin for that server or at least and account with some elevated credentials then this may not work for you.

nkript.screen1

Once you successfully connect to the server, a list of the sites on the server will be loaded along with any virtual directories (since they could potentially contain a web.config file). At this point you can simply browse around and find the web.config you’re wanting to encrypt.

nkript.screen2

It’s worth noting that if there aren’t any web.config (that name specifically) found inside the directory then it won’t be listed. If you happened to have something named web.temp.config then it won’t show up on this list.

At this point the program is going to do a little painful WMI magic and connect out to your server and load the web.config file into the view. The config file will be parsed and all the root nodes will be listed as available to be encrypted.

nkript.screen3

There are apparently some rules about what can or cannot be encrypted, so if the actual aspnet_regiis call fails, you’ll just end up with the same file as before, but you don’t get an explicit message as to why (still trying to find out how I can access messages like that in a semi-reliable WMI fashion).

There isn’t much configuration for this application. The default settings are used to perform the encryption and decryption of the web.config files, so if you are wanting to add some features on you are more than welcome to add them in. I’d love to hear about your changes so I can add them to this version.

It’s not hard to encrypt your web.config files and keep your sensitive information safe. The command line tool aspnet_regiis offers a lot of great functions to further protect your data. Hopefully, this tool allows you to get your work done even faster.

Now if you’ll excuse me, I need to share this tool with #EpicFailVendor. I dunno about the rest of you you but enough is enough! I’ve had it with these monkey fighting vendors not encrypting their their Monday to Friday web.configs!

Mandatory Disclaimer: This program is certified as ‘Works On My Machine’ – The author makes no warranties about how it might behave in your environment (but most likely you have nothing to worry about).

Downloads

Download Nkrypt.exe (Web.config Encryption Tool)

Download Nkrypt.zip (Source Code)

.

After posting this article I got an interesting response from another person that web.config encryption is ‘pointless’ — I thought it was interesting enough to do a follow up blog post about it.

Written by hugoware

July 16, 2009 at 6:20 am

The Mystery Behind ‘Yield’

with 2 comments

If you’ve been coding with .NET for awhile then you’ve most likely encountered a method that returns IEnumerable<T>. If you’re like me, you realize that this returns a list of items your can loop through and evaluate. If you ever dug into the code you may have found a funny looking return statement yield return.

It’s basically just an array, right? We’re just returning each value as a collection to loop over aren’t we? Well, it wouldn’t be the first time that someone (as in myself) misunderstood the purpose of it but there really is a difference.

Let’s look at a fairly common example of returning collections.

The Usual Suspects

private string[] _Names = { "Joe", "Mary", "Bob" };

//a collection of names using a string array
public string[] GetResultsAsArray() {
    List<string> results = new List<string>();
    foreach (string name in this._Names) {
        Console.WriteLine("In GetResultsAsArray() : {0}", name);
        results.Add(name);
    }
    return results.ToArray();
}

//a collection of names using IEnumerable<string>
public IEnumerable<string> GetResultsAsEnumerable() {
    foreach (string name in this._Names) {
        Console.WriteLine("In GetResultsAsEnumerable() : {0}", name);
        yield return name;
    }
}

This is two common looking examples. The first is similar to what that joker on StackOverflow had said in the link above. The second uses yield return to return results.

So if we were to assign these values to a variable, what would our Console read?

var array = GetResultsAsArray();
var enumerable = GetResultsAsEnumerable();
Console.ReadKey();

In GetResultsAsArray() : Joe
In GetResultsAsArray() : Mary
In GetResultsAsArray() : Bob

Now, the first time I came across this I was shocked – I know I assigned my results — what happened?

As it turns out, there is this little thing called lazy evaluation in play here – Unless we need it, the method doesn’t get called. And since we aren’t using our results anywhere, the method is never actually executed.

Lazy Yet Eager

So we’ve determined that unless we use the results of our method, the method won’t ever be executed, which on one hand is actually really quite a handy feature.

Now here is another question for you, when we do use our results — what happens then? Consider this little bit of code.

Console.WriteLine("Array -- ");
foreach (string result in GetResultsAsArray()) {
    Console.WriteLine("In the array loop : " + result);
}

Console.WriteLine("\nEnumerable -- ");
foreach (string result in GetResultsAsEnumerable()) {
    Console.WriteLine("In the enumerable loop : " + result);
}

Console.ReadKey();

Array —
In GetResultsAsArray() : Joe
In GetResultsAsArray() : Mary
In GetResultsAsArray() : Bob
In the array loop : Joe
In the array loop : Mary
In the array loop : Bob

Enumerable —
In GetResultsAsEnumerable() : Joe
In the enumerable loop : Joe
In GetResultsAsEnumerable() : Mary
In the enumerable loop : Mary
In GetResultsAsEnumerable() : Bob
In the enumerable loop : Bob

Each time yield return sent a value back to our loop it was evaluated immediately! For being lazy code, this certainly was quick to give us our answers!

Lazy — And Maybe Late For The Party

Here’s an example where being lazy will get you into trouble, especially if you aren’t clear what it does.

IEnumerable<SearchResult> results;
using (SearchEngine search = new SearchEngine()) {
    results = search.GetEnumerableSearchResults();
}
foreach(SearchResult item in results) {
    //KABOOM!!
}

So what’s wrong with this code? I’ll tell you what – It’s that lazy, good-for-nothing call to GetEnumerableSearchResults(), that’s what!

Since our code doesn’t get evaluated until after we’ve already disposed our object, there isn’t anything there when the method is finally called! Looks like someone kicked into gear a little too late.

Of course code like this has many practical uses, so just make sure that you use it correctly and you’ll find it to be a valuable addition to your programming tool kit.

Don’t Trust Nobody… except your Mother*

So as it turns out there really is a difference between the two, and don’t let any of those fools on StackOverflow tell you otherwise, even if that fool is me!.

*A saying my Italian grandfather used to say.

Written by hugoware

July 13, 2009 at 11:28 pm

Nothing Gets Done When You’re Out Of Town — Ever

with 2 comments

I was out of town this weekend, formatting my computer and chillin’ with my daughters, so the time to work on a technical blog post was pretty much non-existent. I did run into a very disappointing problem with the Vista install that shocked me that I would need to fix (manually loading drivers at the start of the installation – certainly not ‘grandma user-friendly)

Despite that fact I had no time for a technical post, I did get some time to test and verify my screencast software was working like it was before.

This screencast I have a special guest with me, my three-year old daughter Cassandra, showing us some of her favorite technologies on Vista.

This isn’t programming related, just something fun I did this weekend with my kid talking about her favorite games — and she’s talking at the start so have your speakers down


screencast-3

.

Written by hugoware

July 13, 2009 at 7:41 am

Simulate Threading Using Javascript

with 9 comments

One of the cool things about .NET is how easy it is to create more than one thread for your application to run on. On a recent project I had to make many calls to different web services on our network. They were all identical, but each call took quite awhile, roughly around 2 or 3 seconds each.

Instead of doing one at a time, I created 10 separate threads and then merged the results together. Instead of taking around 20 seconds, the calls were reduced to the length of the slowest call. (Web Services also have an Asynchronous method to call a service, so that is an alternative as well).

So What Does This Have To Do With Javascript?

In Javascript, any long running process will cause a noticeable lag for a user. Buttons won’t respond, links don’t do anything, the screen may even turn white — clearly not the user experience we want to deliver.

Recently I was experimenting with joining records using jLinq. jLinq was doing fairly well with the records I was using – I had about 850 records to join against a handful (about 10) of other records. The process finished in around 250ms to 500ms. I was pretty satisfied — until I tried a different set of records…

A different set of records, around 90, crippled the browser. After about 8 seconds the browser finally released itself and we were back in business. Yikes.

Simulating A Thread

So what are the options here? Well unless someone has built threading into Javascript then we’re forced to come with a more creative solution — enter setTimeout.

If you’ve read some of my blog posts before, you know I’m a big fan of enclosures. Using Javascript we can take advantage of both enclosures and setTimeout to try and simulate threading and reduce the time a browser is locked up.

So let’s say we’re working with a really large loop, say around 500,000 records – What can we do? One idea is to break up the work into smaller, more manageable chunks.


//loops through an array in segments
var threadedLoop = function(array) {
	var self = this;
	
	//holds the threaded work
	var thread = {
		work: null,
		wait: null,
		index: 0,
		total: array.length,
		finished: false
	};
	
	//set the properties for the class
	this.collection = array;
	this.finish = function() { };
	this.action = function() { throw "You must provide the action to do for each element"; };
	this.interval = 1;
	
	//set this to public so it can be changed
	var chunk = parseInt(thread.total * .005);
	this.chunk = (chunk == NaN || chunk == 0) ? thread.total : chunk;
	
	
	//end the thread interval
	thread.clear = function() {
		window.clearInterval(thread.work);
		window.clearTimeout(thread.wait);
		thread.work = null;	
		thread.wait = null;
	};
	
	//checks to run the finish method
	thread.end = function() {
		if (thread.finished) { return; }
		self.finish();
		thread.finished = true;
	};
	
	//set the function that handles the work
	thread.process = function() {
		if (thread.index >= thread.total) { return false; }
	
		//thread, do a chunk of the work
		if (thread.work) {
			var part = Math.min((thread.index + self.chunk), thread.total);
			while (thread.index++ < part) {
				self.action(self.collection&#91;thread.index&#93;, thread.index, thread.total);
			}					
		}
		else {
		
			//no thread, just finish the work
			while(thread.index++ < thread.total) {
				self.action(self.collection&#91;thread.index&#93;, thread.index, thread.total);
			}	
		}
		
		//check for the end of the thread
		if (thread.index >= thread.total) { 
			thread.clear(); 
			thread.end();
		}
		
		//return the process took place
		return true;
		
	};
	
	//set the working process
	self.start = function() {
		thread.finished = false;
		thread.index = 0;
		thread.work = window.setInterval(thread.process, self.interval);
	};
	
	//stop threading and finish the work
	self.wait = function(timeout) {

		//create the waiting function
		var complete = function() {
			thread.clear();
			thread.process();
			thread.end();
		};
		
		//if there is no time, just run it now
		if (!timeout) {
			complete();
		}
		else {
			thread.wait = window.setTimeout(complete, timeout);
		}
	};

};

// Note: this class is not battle-tested, just personal testing on large arrays

This example class allows us to pass in a loop and then supply a few actions for us to use on each pass. The idea here is that if we do a section, pause for the browser to catch up, and then resume work.

How exactly do you use this? Well let’s just say we have a really large loop of strings we’re wanting to compare…

var array = [];
for (var i = 0; i < 500000; i++) { array.push("this is some long string"); } [/sourcecode] That's a lot of work to check all those - Let's move it into our new class we created... [sourcecode language='javascript'] //create our new class var work = new threadedLoop(array); //create the action to compare each item with work.action = function(item, index, total) { var check = (item == "this is some long string comparison to slow it down"); document.body.innerHTML = "Item " + index + " of " + total; }; //another action to use when our loop is done work.finish = function(thread) { alert("Thread finished!"); }; //and start our 'thread' work.start(); [/sourcecode] If you run this test in a browser, you'll see that our page is updated as each pass of the array is completed. This way our browser remains 'responsive' to a degree, but continues to process our work in the background. This code allows you to set a few additional properties as well as an additional function.

  • chunk: The number of records to loop through on each interval. The default is numberOfRecords * 0.005.
  • interval: The number of milliseconds to wait between passes. The default is 1. A longer value gives the browser more time to recover, but makes the loop take longer.
  • wait([timeout]): Waits the number of milliseconds before canceling the thread and blocking the browser until the work finishes. If no time is provided, as in left blank, the waiting starts immediately.

Threading Possibilities?

It’s always amazing to see what enclosures can do – I’m not so sure how simple this same creation would be in Javascript without them. With a little bit of code we can create a half-way decent attempt at creating an asynchronous experience for our user, even if we have a lot of work to do.

Could your heavy client side scripts benefit from ‘threading’?

Written by hugoware

July 10, 2009 at 6:05 am