Re: ASP.NET Custom Authentication Problems

I just got a comment from an old post from over 2 years ago about some custom auth problems I had.  It's funny looking back that far to see how you were.  As with all typical developers, I look back and laugh at myself.  πŸ™‚

The question posted was if I could share my custom authentication code.  The fact of the matter is, the way I was doing authentication at the time was kind of silly and I thought I'd post how we do it now.  It's much simpler and uses everything that's already built into ASP.NET 2.0 already.  When a user logs into your site (using whatever type of authentication you want), the Context.User (same User object that shows up on the Page class, etc) is set to an IPrincipal.  Depending on what "username" you passed in for it to tack on to the cookie, you'll be ablel to access a key for looking up more detailsl about the user.  Then the same applies from the rest of my 2 year old post.  Create a BasePage class that inherits from Page and shadow the User property with your own.  Here's the code from our platform in the BasePage class.

public bool IsAuthenticated
{

get { return Request.IsAuthenticated; }
}

private string username;
public string Username
{

get

{

if (username == null)

{

if (IsAuthenticated)

username = base.User.Identity.Name;

else

username = "";

}

return username;

}
}

private bool isUserSet;
private EvNetUser user;
public new EvNetUser User
{

get

{

if (!isUserSet)

{

if (IsAuthenticated)

user = Users.Retrieve(Username);

isUserSet = true;

}

return user;

}
}

Now anywhere in our site we can say Page.User and get back an object filled with everything we need to know about the current user.  If the request is anonymous, Page.User will return null.  Hope this helps Mohammed!

How to Use Embedded JavaScript Files in ASP.NET AJAX

I'm writing up a post about creating custom client controls at the moment (well, as of a few minutes ago anyway).  It is getting pretty long and it's way past my bedtime.  So I thought in the meantime I'd post a quick little blurb about how you can use JavaScript from an assembly for your ASP.NET AJAX code and why you would want to.

It's pretty easy to setup a .js file in your web project with some code in it.  Sometimes though the code in said file is associated with say a custom client control (something that inherits from Sys.UI.Control) that is in its own assembly (not your web project).  This is how our controls are setup for our platform.  This is so we can use the same controls across Channel 9, Channel 10, etc.  The problem is now that we have code in js files, they have to be replicated across all our web projects and that's just no fun.  So instead we moved to having the js files embedded in our main class library.  The server controls register these files and they are then pulled out of the assembly and sent down to the client and cached.  Here's how to set this up yourself…

Add the following line as the last line in your js file:

if (Sys != undefined) Sys.Application.notifyScriptLoaded();

This tells ASP.NET AJAX that the file is done loading.  This is needed because all embedded js files stream down in the same "file" so the end of the file isn't necessarily the end of what's streamed down to the client.  Unlike when you just like to a js file regularly.

Now, in Visual Studio go to the properties window while your js file is selected.  Change the Build Action to Embedded Resource.  This will compile the file into the assembly as a resource.  If you open up reflector and venture through, you'll find the js file.  Now in your server control, add this line so ASP.NET knows about the resource (and what mime type to send it down as):

[assembly: WebResource("EvNet.Web.Templates.Scripts.Toolbar.js", "text/javascript")]

Now anytime you add a ScriptReference to a ScriptManager, your file will be streamed down to the client.  Just specify the resource name (This is the physical file path down to the file starting at the root of your class library with slashes replaced by periods [see below]) and the assembly the resource is in and you're done.  No need to worry about where the file is anymore.  πŸ™‚  This of course works when implementing IScriptControl.GetScriptReferences in your server control too:

public IEnumerable<ScriptReference> GetScriptReferences()
{
     return new ScriptReference[] { new ScriptReference("EvNet.Web.Templates.Scripts.Toolbar.js", "EvNet") };
}

Enjoy!

Intro to ASP.NET AJAX Custom Client Controls

So in my journey to explore our platform that runs Channel 9 and Channel 10 and soon a few more sites continues with a walkthrough of some basics on creating custom controls in ASP.NET AJAX.  More than likely if you're reading this it's because you already know about ASP.NET AJAX 1.0 or have at least heard about it.  You found this post through a search on your favorite search engine, saw it on the weblogs.asp.net home page, subscribe to my feed or someone linked to it (here's hoping).  If you have no idea what it is, well…go check out the site and come back.  πŸ™‚  That's probably the easiest way to explain it.

ASP.NET AJAX 1.0 Basics

ASP.NET AJAX has basically built on top of JavaScript to make it cross-browser compatible as a framework on top.  This makes developing things like custom client controls very similar to building classes in .NET.  There are namespaces, classes, enums, methods, fields, properties, inheritance, etc.  There is also a server control architecture to allow you to build server controls to configure and instantiate custom client controls.  I'll talk about this later.  The best way to think of ASP.NET AJAX is to think of it as a client technology.  Yes there are server aspects, but the server just acts as the middle man.  It gets requests for pages and servers and returns the appropriate data.  This is how it is today except now we can push more logic down to the client so the server doesn't have to render UI logic as much.

UpdatePanel

While this post isn't going to focus on the UpdatePanel, it's good to know about it and how it compares to custom controls.  The UpdatePanel is gold.  Plain and simple.  Build some code on your ASP.NET page, say a GridView with some data bound to it.  It works great and just does the usual postbacks.  Page through some data, yippee.  Now surround it with an UpdatePanel and watch the "magic".  Paging now without postbacks?  Glorious!  Like all great things that make our lives easier,  you can definitely overuse it.  Working with ViewState just like a normal postback would, sending it back and forth between requests, is its greatest strength and weakness.  You can still have the same problems of bloated ViewState that can make those monthly bandwidth bills for your site go up and up.  The UpdatePanel is great for quick and dirty AJAX.  If you have a simple form you want to make fancy, it is the right tool.  A good example where the UpdatePanel probably isn't the best answer to solve your problem is showing and hiding lots of divs.  Things that can easily be done through javascript should.  This saves lots of server request and makes it so you don't really need any ViewState because the work will be done on the client.

Sys.UI.Control

Sys.UI.Control inherits from Sys.UI.Component.  Just like any Windows application, a component in ASP.NET AJAX is a client side control that has no UI (like a timer) and a control has UI.  As I mentioned above, ASP.NET AJAX helps us push UI logic off of the server and onto the client.  Sys.UI.Control is a base type you can inherit from to build your control on.  It takes care of all the basics like with DOM element it's associated with for its UI and has methods like initialize and dispose.  Let's build a quick calculator control.  Hey, it wouldn't be a typical example if it were anything else but a calculator.  πŸ˜‰

Have ASP.NET AJAX 1.0 installed and create a new website using the ASP.NET AJAX-Enabled Web Site template and call it Calculator.

Visual Representation

All we should need for this is two textboxes, a dropdownlist, a button and a label to display the answer in.  Create a new Web User Control called Calculator.ascx.

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Calculator.ascx.cs" Inherits="Calculator" EnableViewState="false" %>
Number 1:
<asp:TextBox ID="Number1TextBox" runat="server"></asp:TextBox><br />
Type: <asp:DropDownList ID="TypeDropDownList" runat="server"></asp:DropDownList><br />
Number 2: <asp:TextBox ID="Number2TextBox" runat="server"></asp:TextBox><br />
<
asp:Button ID="CalculateButton" runat="server" Text="Calculate" />
Total: <asp:Label ID="TotalLabel" runat="server" Font-Bold="true"></asp:Label>

@ Control Language="C#" AutoEventWireup="true" CodeFile="Calculator.ascx.cs" Inherits="Calculator" EnableViewState="false" %>
Number 1:
<asp:TextBox ID="Number1TextBox" runat="server"></asp:TextBox><br />
Type: <asp:DropDownList ID="TypeDropDownList" runat="server"></asp:DropDownList><br />
Number 2: <asp:TextBox ID="Number2TextBox" runat="server"></asp:TextBox><br />
<
asp:Button ID="CalculateButton" runat="server" Text="Calculate" />
Total: <asp:Label ID="TotalLabel" runat="server" Font-Bold="true"></asp:Label>

Definitely no prettying up there. Just the basics.  The calculator example may not be the best use of a custom control, but it keeps it simple so you learn what should be learned.

Client Code

First things first, we should register a namespace for our class that's going to represent the definition of our client representation of the calculator.  Create a new .js file called Calculator and add the following to it.

Type.registerNamespace("Porter.Erik");

"Porter.Erik");

Then we need to create and register the class itself.

 

blah

Web Service

blah

It's been a really interesting journey watching ASP.NET AJAX grow up.  I got to see very early builds of it (this was a few weeks before the first CTP) before I joined Microsoft when I was an ASP Insider and while the potential was there, it was still in its infancy and had a long way to go.  This was in October 2005.  Now it's all grown up and turned into a comprehensive client library, awesome integration with ASP.NET server controls and a Control Toolkit.  Things are only going to get better with full integration into Orcas.  Good times!

So far we're just using custom controls in basic places on Channel 9 like the wiki edit control, reply editor and a couple others.  We're currently using the UpdatePanel for our EntryList control because it was simple to get going.  Between the beta of Channel 9 and RTW, I will probably switch it over to being a custom control.  This will more than likely be a blog post on its own and will demonstrate some advanced techniques.

There's more code from our platform in the pipeline.  I'm not sure what to talk about next, but it may be our Virtual Path Provider setup or Templating scheme.

ASP.NET FindControl Recursive with Generics

While working on the new version of Channel 9, part of my job this time around was to "templatize" our entire community platform.  The way everything is set up now, aspx files are read in through the Virtual Path Provider (VPP), additional settings in the Page directive are set based off of database settings and the page is rendered.  All our controls are now ascx files with the CodeFileBaseClass set to a class that implements all the code.  This allows us to easily setup new controls and templates for our different sites if new ones are needed.  Right now, Channel 9 and Channel 10 are the only two sites that will be running this code.  In the halfway near future, VisitMIX and a yet to be named Student focused site will run this code as well, so templating was very important.  My other job for this sprint was to add ASP.NET AJAX functionality to the site.  As we get closer to launching the beta you'll see more posts from me sampling some of our code and techniques especially around ASP.NET AJAX.

The new EntryList control that I created takes a List<Entry>.  The control has a setting to let us set which ascx file we want to use to represent each Entry in the list.  These are loaded using Page.LoadControl.  The same thing goes for the Pager and Filters control in the header and footer of the EntryList.  All of these controls implement different interfaces so we can throw in different ones and look them up generically.  I don't necessarily know the names of these controls and needed a way to look them up by the interfaces they implement.  So I thought, "hey, I'll bet generics could help me out here."  I got the below code written, but unfortunately couldn't figure out how to properly cast the control by the type passed in.  My next door neighbor, our resident Sampy, helped me figure out that I needed to force the type coming in to be a reference (hence the "where T : class" part).  Here's the resulting code…

public static T FindControl<T>(System.Web.UI.ControlCollection Controls) where T : class
{
     T found =
default(T);

     if (Controls != null && Controls.Count > 0)
     {
         
for (int i = 0; i < Controls.Count; i++)
          {
              
if (Controls[i] is T)
               {
                    found = Controls[i]
as T;
                   
break;
               }
              
else
                   
found = FindControl<T>(Controls[i].Controls);
          }
     }

     return found;
}

Unlike a recursive method that's not generic, you would have to pass in the type as a parameter to the method, which would get passed down through every method call, and you'd have to cast the found control on every call you made to FindControl.  That wouldn't be a huge deal, but there is something nice about simplicity.  πŸ™‚

IMyInterface myControl = FindControl<IMyInterface>(this.Controls);

Note: This only returns the first instance of a control.  You could easily pass in a references List<IMyInterface> and add to it as you find them. 

This isn't break through code or anything, but it's fun for us, the dev geeks.  Expect to see more posts soon about coding techniques in our platform.