Scott Hanselman

ASP.NET MVC Source Code Available

March 21, 2008 Comment on this post [5] Posted in ASP.NET | ASP.NET MVC | Programming | Source Code
Sponsored By

image My boss's boss has blogged about what's been going on this week: The ASP.NET MVC Source is up on CodePlex at http://www.codeplex.com/aspnet.

You can download, read and compile it now.

The goal is to start releasing drops really often. If you're into it, then watch the source code tab, if not, that's cool too, you can wait until it releases later.

You can enter bugs in the issue tracker or complain in the forums and watch the roadmap as it evolves. You can see how to compile it (unzip and build) as well.

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Hanselminutes Podcast 104 - Dave Laribee on ALT.NET

March 20, 2008 Comment on this post [6] Posted in ASP.NET MVC | Learning .NET | Nant | NCover | NUnit | Podcast
Sponsored By

RWS2-Big My one-hundred-and-fourth podcast is up. In this episode I talk to the always thought-provoking David Laribee (blog) who coined the term ALT.NET just last year. It's turned into a Open Spaces Conference and continues to challenge the status quo, reminding .NET developers of the importance of being agile and enabling processes for continuous improvement.

What does it mean to be to be ALT.NET? In short it signifies:

  1. You’re the type of developer who uses what works while keeping an eye out for a better way.
  2. You reach outside the mainstream to adopt the best of any community: Open Source, Agile, Java, Ruby, etc.
  3. You’re not content with the status quo. Things can always be better expressed, more elegant and simple, more mutable, higher quality, etc.
  4. You know tools are great, but they only take you so far. It’s the principles and knowledge that really matter. The best tools are those that embed the knowledge and encourage the principles 

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

If you have trouble downloading, or your download is slow, do try the torrent with µtorrent or another BitTorrent Downloader.

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Check out their UI Suite of controls for ASP.NET. It's very hardcore stuff. One of the things I appreciate about Telerik is their commitment to completeness. For example, they have a page about their Right-to-Left support while some vendors have zero support, or don't bother testing. They also are committed to XHTML compliance and publish their roadmap. It's nice when your controls vendor is very transparent.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Squeezing the most out of IIS7 Media Bit Rate Throttling

March 20, 2008 Comment on this post [5] Posted in HttpHandler | HttpModule | IIS | Podcast
Sponsored By

image ScottGu blogged about the IIS 7.0 Bit Rate Throttling Module being released. Since IIS 7.0 is totally modular (finally!) I think you'll see lots of increasingly useful modules coming out from the team. I know a couple of cool people over there so I get a little insight into what's coming soon.

Since I'm into podcasting some, I started bugging a PM in the IIS team about the Bit Rate stuff in order to dig deeper into what's going on and how I can exploit it. The next step will be to convince Carl, my producer, that we need to get on this stuff.

His Gu-ness has a better description of Bit Rate Throttling that I could write, so here's the meat of it:

Progressive Download Scenario

In a progressive download scenario a client (like Flash or Silverlight) downloads a video directly off of a web-server, and begins playing it once enough video is downloaded for it to play smoothly.

The benefit of using a progressive download approach is that it is super easy to setup on a web-server. Just copy/ftp a video up to a web-server, obtain a URL to it, and you can wire it up to a video client player. It doesn't require any custom web-server configuration, nor require a streaming server to be installed, in order to enable.

The downside of using a progressive video download approach, though, is that web-servers are by default designed to download files as fast as possible.  So when a user clicks to watch a video on your site, your web-server will attempt to transmit it to the client as fast as possible.  This is fine if the user decides to watch the entire video.  But if the user stops watching the content half way through the video (or navigates to a different page), you will have downloaded a bunch of video content that will never be watched.

If the remaining un-watched video content is several megabytes (or even tens of megabytes) in size, you will end up over time spending a lot of money on bandwidth that is not benefiting your business/site at all....

That's the problem this module tries to solve. If you think it's not a problem, talk to me or Carl. It costs a metric buttload to pay for bandwidth of my podcast and it's a harder problem to solve than you think. (Yes, every show has bittorrent as an option, but few Feed Readers use it). A surprising number of folks visit the site and just click on a show and start listening in whatever Media Player they dig.

If someone starts streaming the first 20 seconds of a 45 minute show, decides they don't like it and stops, we may have to pay for the whole 45 minutes as it might already have been downloaded! This is also good for screencasts.

The media throttling stuff looks at the file you're downloading, "bursts" the first chunk to make the "buffering" part of your listening experience as fast as possible, then it throttles the bandwidth from that point on, making sure it doesn't have to buffer again, but still saving bandwidth.

There's some technical details over here that I care about like (emphasis mine) and more technical details here:

"It's also worth noting that the throttler uses a high-performance asyncronous loop to push the data out, without tying up server threads for what can be a very long operation. For responses coming from files (like most large video files), it also does not need to read the content's of the file being sent into memory, instead just instructing http.sys to send portions of the file out to the client at a time.  Because of this, it won't significantly affect your memory usage. While this mechanism is not as efficient as http.sys's own site-wide bandwidth throttling (which cannot be used to do what we are trying to accomplish here), it is pretty much as lean as it can be."

So, I'm going to give this a try on my local machine. I'll start with a recent WMA of the show and put it in a folder under IIS.

image

Notice that this show is a WMA encoded at 32kps (for low-fi/low-bandwidth listeners) and is in http://mymachine/show. I turned on Bit Rate Throttling from the IIS Management Console.

You can set the throttle rate as a percentage of the encoded rate. I'm leaving it as 100%, so that's 100% of 32kbps after the initial burst of 20 seconds.

image

ASIDE: One of the things that is way better in IIS7 than 6 is dealing with permissions and "blocking issues." You know, when you setup a folder, configure the VDir and you get something like "permission denied" then you spend 20 minutes trying to figure out why you can't serve a freaking text file out of a folder? IIS7 has a "Test Settings" dialog like this that just saved me those 20 minutes.

image

Ok, back to business. When I hit this file I get the quick burst, then throttling hits to slow it down to a value above, but close to, the encoded rate.

image

If I try the hi-fi version of the WMA, you can see the bitrate is higher, so the throttling is smart enough to slow the bandwidth but it's always higher than the encoded rate so there's no skipping.

image

Here's what the burst followed by the throttling looks like charted.

image

Remember that this is just a stock IIS Web Server plus this new module, so we're not running Media Services or a Streaming Server or whatever.

Extending Bit Rate Throttling with Custom Code

I thought this was cool and everything, but I immediately brought up the question that some of my users download directly via RSS Readers, while others click the "play now" button and stream. I don't want to throttle the bandwidth for folks who are downloading, just those who stream. However, I'm not running a streaming server (meaning, that everything is over http://, not some mms:// funky port) so I need to differentiate between the two.

I figured there were a couple ways to handle this. I could make different VDirs in IIS mapped to the same files and have BRT (Bit Rate Throttling) turned off on one and on for the other. It'd work, but meh.

Or, I could add Windows-Media-Player/11.0.5721.5145 the end of the URL and turn BRT off for those using a custom coded IIS Module.

How to I write a module? I could make a bin folder and build a DLL, etc, but I could also just make an App_Code folder, apply the appropriate permissions...

image

...and put the source for my custom module in it. I actually wrote it in Notepad.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.IO;

namespace Hanselmodules
{
    public class CustomBRTModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.BeginRequest += new EventHandler(OnBeginRequest);
        }

        public void Dispose(){}

        public void OnBeginRequest(Object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication)source;
            HttpContext context = app.Context;

            if (context.Request.QueryString["download"] == "true") //make these fast
            {
                context.Request.ServerVariables.Set("ResponseThrottler-InitialSendSize", "60000");
                context.Request.ServerVariables.Set("ResponseThrottler-Rate", "6000");
            }
        }
    }
}

Basically, I just check for ?download=true on my URL and set my initial send size and rate to really big numbers. (Certainly they could be bigger, come from config, or be calculated by me.)

From the Modules section of the IIS Manager I hit Add Module and my new module shows up. I name it and select it and it appears in the web.config in my /show folder.

 image

After installing this module if I hit: http://mymachine/show/foo.wma I get appropriate throttling, and if I hit http://mymachine/show/foo.wma?download=true I don't. Below you can see screenshots of one download finished at 9megs a second while the other is throttled at 28K/s.

image

Now, this is just one example. I might want to do something cool with JavaScript that appends the ?download if a person clicks a button, or I might want to "sniff" for browser User-Agents versus Media Players like "Windows-Media-Player/11.0.5721.5145" or iTunes/Zune or the like. It's up to me, as writing the IIS7 modules is easy.

You could even use BRT and techniques like this to throttle bandwidth to data (non-media) files, and give different chunks of bandwidth to different levels of users. My module could have checked if it was a paid user and give them preferred download speeds. Pretty sweet. Now, off to talk to Carl! :)

Related Links:

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Twitter: The Uselessfulness of Micro-blogging

March 19, 2008 Comment on this post [13] Posted in Musings
Sponsored By

twitter20070405 I haven't used Instant Messaging for anything significant in months. Why?

Last May (!) I used the Twitter micro-blogging service and made a post every time I managed my Diabetes. It ended up being a pretty cool thing and even was on the evening News in San Francisco.

The rise of blogs brought conversations on the 'net more out in the open. Blogging enabled conversation via essay, but as blogs have matured, posts have gotten longer and longer and threads more difficult to follow. Now, most posts are jumping off points for the more interesting conversations that inevitably move to the comments.

Public debates and conversations still exist on Mailing Lists, IRC, and USENET. Private instant messaging is about connecting and conversing but is usually one to one, which certainly doesn't conserve my keystrokes. However, these conversations miss three useful things.

  • Constraints
    • Everyone uses a different mail client or USENET client and formatting and replies make things sloppy at best.
    • Some folks comment inline, other quote, still others copy-paste, all of which makes it hard to follow.
  • Permalinks
    • Yes, aggregators like Google Groups can make Permalinks (URLs) to conversations, but it's still clunky at best.
    • IRC conversations have no permalinks and virtually no searchable logs.
  • API
    • The APIs for posting and reading to and from IRC and USENET are not easy to implement (although, they are very well understood, you can't bang a client out in an hour).

Twitter offers/imposes all three. You can "tweet" a max of 140 characters. Every tweet can be linked directly to and lives forever. There's a clear API. Any one or all of these things may seem lame or a deal-breaker to you, but these very things are what makes it useful for public conversation and sharing.

Twitter as Conversation Starter

Twitter is just one of the Microblogging services out there, but it's got a nice RESTesque API that has encouraged a number of a cool Twitter Clients like Witty, Twhirl, TinyTwitter (Windows Mobile) and others, as well as a nice mobile site at http://m.twitter.com. It also supports SMS so you can send and received Twitter messages with no UI or client at all.

Twitter's API also has spawned statistics sights like Twitterholic and Tweeterboard as well as fun things like Twaiku's (Twitter Haiku's) and Twoosh, when you use exactly the maximum of 140 characters in your "Tweets."

I'm finding that I use Twitter more to chat with folks and interact with the community. There's aspects of presence, as sometimes folks will tweet "heading downtown" and I've used this to have surprise meet-ups and lunches when I just happen to cross paths with someone.

One of the misconceptions about Twitter is that I (a user) need to permissively "follow" you (another user) in order for us to talk. However, one setting change means I'll see any tweet that includes my username preceded by an @ sign. So, the way you respond in Twitter is like this: "@shanselman you rock" and I'll see it.

image

One thing to point out (warn you) about Twitter is that tweets tend to be more sarcastic, silly, non-technical, whatever than on a blog. It's important to remember that what you say on Twitter is public, indexable, and arguably permanent, which is both a good thing and a bad thing, but be aware - The Internet Remembers.

Twitter as Message Bus

There's a number of examples of Twitter being used as a message bus. For example, you can create a Twitter user as a "bot" to be used to send an receive information via an API. One such user is "commuter" that supports the http://commuterfeed.com/ website.

If I "follow" @commuter I can send traffic updates to it like this "@commuter PDX Traffic on I5" and it'll show up on the Commuter Feed.

Twitter for News

I've been getting the majority of my news lately by watching/following the major news outlets that have adopted Twitter, like NPR News, CNN and BBC Tech. Political activists like Dave Winer have been providing commentary via Twitter, and even candidates like Barack Obama have a Twitter presence. Obama has over 16,500 followers at growing on Twitter! Here's a list of the "Twitterati" from http://twitter.alltop.com/.

Twitter as Conference/Subject Tagger

If you're at a conference or in a particular special interest group, you can include a "hashtag" in your tweet like "#mix08." Many folks did this while at Mix08 in Vegas this year and via another service at Hashtags.org a feed was created that allowed not only the folks on the ground to stay in touch, but also for others not in Vegas to follow the conference.

All of these things and more have made (so far) Twitter a really fun, dynamic, and ultimately enriching part of my day.

Feel free to go sign up for Twitter yourself. I'm http://www.twitter.com/shanselman and once you've signed up you can "follow me" and I can follow you and we'll all join the conversation. I encourage you to find a Twitter Client that works for you and give it a try.

How do you find folks you know on Twitter?

You can find folks to follow by letting Twitter check your email contacts, but I have found that just by picking a few folks to follow, then watching who they talk to has been a great way to keep the signal to noise ratio high.

I don't know how long this will last, but I'm finding Twitter to be a nice, fresh way to keep up with friends and community in a 3rd place separate from USENET, Mailing Lists, IRC and IM.

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

The Weekly Source Code 20 - A Web Framework for Every Language

March 19, 2008 Comment on this post [15] Posted in Javascript | PHP | Programming | Ruby | Source Code
Sponsored By


vt102

We just keep oscillating back and forth between thin clients and chubby clients. We started with basic terminals receiving text from the server and displaying it, then added control codes and more smarts until we got into things like VT102 and beyond. We pushed all the User Interface over to the client for rendering.

Now that the Web is squarely here to stay, we've got islands of activeness in the form of browser plugins like Flash and Silverlight, some of which are cross platform and some less-so, but for now my quad-processor machine spends a lot of time either:

  • Waiting for markup to show up
  • Rendering markup

There's a thousand different ways to generate your UIs and send them down to the browser/client for rendering. Turns out there are as many ways as there are languages. If you've got a programming language, there's a web framework for it.

I don't know why this surprises me. Folks love their programming language, whatever it is, and it makes sense that the "ultimate" proof of their language's awesomeness would be the "ultimate web framework."

That said, it still seems funny to me that the greatest (er, most overtly visible) example of a language's superiority is how well it works as a Web Framework angle-bracket generator.

For example, Arc is Paul Graham's new LISP dialect that a number of people are talking about (with varying degrees of enthusiasm).  A tutorial on Arc is available here and there's an "Arc Challenge" being discussed here as folks try to this slightly more complex Hello World example:

"First generate a page with an input field and a submit button. If the user clicks on submit, he gets a second page with a link saying "click here." If he clicks on that, he gets a third page saying "you said: ..." where ... was whatever he put in the input field. This has to happen without the value being passed in the url; it should not be possible to change the behavior of the third page by editing the url in the second."

In Arc/LISP it looks like this:

  (defop said req
    (aform [w/link (pr "you said: " (arg _ "foo"))
             (pr "click here")]
      (input "foo")
      (submit)))

It's pretty terse to look at if you're used to doing things in more conventional languages. There's a lot of fun solutions like this entirely client-side one in JQuery:

$('body').append('<input id = "myInput" /><input type = "submit" />')
    .find('input[@type=submit]').click(function() {
       val = $('#myInput').val();
       $('body').html('<a href = '#'>click here</a>').find('a').click(function() {
          $('body').html('You said: ' + val);
       });
    });

Other examples include:

#!/usr/bin/env ruby
  require "ramaze"
  class MainController < Ramaze::Controller
    def index
      if f = session['foo'] then "you said #{f}"
      elsif session['foo'] = request['foo'] then A("click Here", :href => '/')
      else '<form><input name="foo" /><input type="submit"></form>'
      end
    end
  end
  Ramaze.start :port => 7001
  __END__ 

Then Rails:

def said
    if request.method == :post
      session[:said] = params[:said]
      render :action => "clickhere"
    else
      render :action => "result" if session[:said]
    end
  end

  default template said.rhtml:
  <% form_tag do %><%= text_field_tag "said", "" %><%= submit_tag %><% end %>

  clickhere.rhtml:
  <%= link_to "click here", "" %>
  
  result.rhtml:
  You said <%= session[:said] %>
| something |	
something := self request: 'Say something'.	
self inform: 'Click here'.	
self inform: something
serveAs "said" $ hasIndex $ \x -> "click me" `linksTo` (text ("You said " ++ x))
<%@ Page Language="C#" ClassName="WebApplication1._Default" %>
  <script runat="server">
    // C# and ASP.NET
    protected void SubmitButton_Click(object sender, EventArgs e)
    {
        MultiView1.ActiveViewIndex = 1;
    }
    protected void ClickHereButton_Click(object sender, EventArgs e)
    {
        SaidLabel.Text = string.Concat("You said: ", SayTextBox.Text);
        MultiView1.ActiveViewIndex = 2;
    }
  </script>

  <html>
  <head runat="server">
    <title></title>
  </head>
  <body>
    <form id="form1" runat="server">
      <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
        <asp:View runat="server">
          <asp:TextBox ID="SayTextBox" runat="server" />
          <asp:Button ID="SubmitButton" runat="server" Text="Submit" OnClick="SubmitButton_Click" />
        </asp:View>
        <asp:View runat="server">
          <asp:LinkButton ID="ClickHereButton" runat="server" Text="Click Here" OnClick="ClickHereButton_Click" />
        </asp:View>
        <asp:View runat="server">
          <asp:Label ID="SaidLabel" runat="server" />
        </asp:View>
      </asp:MultiView>
    </form>
  </body>
  </html>

Shorter but not-typical ASP.NET:

Shorter but non-idiomatic C#/ASP.NET:

    <%@ Page Language="C#" %>
    <html>
    <head>
    <title>Said</title>
    </head>
    <body>
        <form id="form" runat="server">
            <% if (!IsPostBack) { %>
                <input name="foo" />
                <input type="submit" />
            <% } else if (Request.Form["foo"] != null) {
                Session["foo"] = Request.Form["foo"]; %>
                <a href="javascript:form.submit()">click here</a>
            <% } else { %>
                you said: <%=Session["foo"]%>
            <% } %>
        </form>
     </body>
    </html>

There are so many ways to generate the same result. Big thanks to Ted Glaza for his indirect help on this post.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.