Custom 401 in ASP.NET

Because IIS intercepts your request before you can handle it, you can't just set a 401 page in your custom errors block. While you can still change the default 401 page in IIS, the user will typically get challenged first when you set security with location in the web.config.

You wouldn't do this at all anymore, but I ran into it making a change to a legacy webform app and figured I would save what I found in case I see it again (I am moving 50+ apps).

To handle this you would do something hacky like this:

protected void Application_EndRequest(Object sender, EventArgs e)
    {
        HttpContext context = HttpContext.Current;
        if (context.Response.Status.Substring(0, 3).Equals("401"))
        {
            context.Response.ClearContent();
            context.Response.Redirect("~/AccessDenied.aspx");
        }
    }

One point to note, you can't do this in integrated mode, you would have to drop your app pool to classic mode.

Or you could be one of the cool kids and just rewrite the whole thing from scratch without telling anyone.

ASP.NET MVC 3 Preview 1 is out

Stumbled across this on HAACKED yesterday. Preview 1 for MVC 3 is out. I must be falling behind, it seems like it hasn't been that long since I launched my first MVC 2 app...

I guess the main things to know are:

  Requires .NET 4.0
  Requires Visual Studio 2010

Read more: http://haacked.com/archive/2010/07/27/aspnetmvc3-preview1-released.aspx
             or: http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx

Why VB.NET is a Bad choice

I posted earlier that I recently changed jobs, which means that I went through a good bit of interviewing trying to find the job I thought was right for me at this point in my career.

Some of you may find it silly, but one of the criteria that was pretty important to me was that all new code was going to be written in C# and not in VB.NET. One of my interviewers asked me why.

VB.NET in its very design tries to solve the wrong problem.

Visual Basic.NET is touted as a nice easy to use language for a novice to learn to make applications. The they learn to make applications in VB.NET and continue to write in VB.NET. This comes to the problem. Writing code is easier than reading code. Go ahead, Google it. VB.NET tries to solve the problem of writing code (the easy part) but makes the hard part harder (reading code).

So you spend 6 months creating that jazzy new VB.NET application that saves the world for you company. How long do you spend maintaining and extending that application? 4 or 5 years? Longer?

VB.NET is different.

In this case, different is not good. Different makes the above problem (writing code is easier than reading code) even more obvious. When you are integrating with other code, reading someone else's code, trying to replicate behavior from some other application in your application; most likely you are reading something totally unlike VB.NET. Hell, even if you are rewriting a legacy application, VB.NET isn't even like Visual Basic 6, so you aren't gaining anything there.

C# on the other hand, shares many structural simularities with C, C++, Java, Javascript and others. Even if you can't write in those languages just because you know C#, you can most likely at least get an idea of what is going on by reading them. C++ looks like Moon Language to a VB.NET developer.

Well, you know what? VB.NET looks like Moon Language to everyone except a VB.NET developer.

Writing a dynamic playlist out as an asp.net page

I have an FTP directory that I keep my music in, and I have a Windows Play List file in it (.wpl). Windows Playlist Files are human readable xml files you can alter in notepad, so when I add a new song to the directory, I just open the file and add another line. A wpl file looks like this:

 <?wpl version="1.0"?>
<smil>
    <head>
        <meta name="Generator" content="Microsoft Windows Media Player -- 10.0.0.3646"/>
        <title>Playlist1</title>
    </head>
    <body>
        <seq>
            <media src="http://blogbybob.com/music/mysong.wma" mce_src="http://blogbybob.com/music/mysong.wma"/>
        </seq>
    </body>
</smil>

So, I had a thought one day. Just the one, of course. Would it be nice if I could add the file, and have it show up automatically when I opened media player?

Well, amazingly enough, it is actually pretty easy to do. The main thing to do is "trick" IE into thinking that your wonderful aspx page is actually a wpl file. Fire up Visual Studio, start a new Web Site and go into your default.aspx file.

Highlight all that crap and delete it. Wait, I mean, all of it but the first line. My bad. And I actually named my file music.aspx, but whatever.

Anyhow change the file contents to look like this:

 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="music.aspx.cs" Inherits="_Music" %>

<?

wpl version="1.0"?>
<
smil>
  <
head>
    <
meta name="Generator" content="Microsoft Windows Media Player -- 10.0.0.3646"/>
    <
title>musicbybob</title>
  </
head>
  <
body>
    <
seq>
      <
asp:Literal runat="server" ID="litPlaylist" />
    </
seq>
  </
body>
</
smil>

except your first line should still point to whatever code behind you are using. Right click that guy and choose View Code.

We are going to get rid of all but 2 of the using statements and add some code to the Page_Load event. When you are done it should look like this:

 using System;
using System.IO;

public

   

 

partial class _Music : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    Response.Clear();
    Response.ContentType =
"video/x-ms-wma";
    Response.AddHeader(
"Content-Disposition", "inline;filename=musicbybob.wpl");
    litPlaylist.Text =
string.Empty; DirectoryInfo d = new DirectoryInfo(Server.MapPath("music"));    foreach (FileInfo f in d.GetFiles())
    {
      litPlaylist.Text +=
"<media src=\"http://" + Request.Url.Host +"/"+ Request.ApplicationPath + "/music/" + f.Name + "\"/>";
    }
  }
}

Except your class name should match whatever is in your aspx page. Yeah, I used some crappy variable names and was all around lazy, but it works, and sometime I *like* to be lazy. This will read anything in the music folder below where this file lives. You can also add other wpl files in the music folder that point to other places if you have music spread around. Music added to those "other" places won't be dynamically added though. The code also doesn't navigate subdirectories in your music folder.

Or so I assume, I never actually tried it.