Get SqlDataSource To Retrieve DefaultValue of Current User (ExpressionBuilder with ASP.NET 2.0)

Abstract

This article shows how to use Expression Builders in ASP.NET 2.0 to retrieve the current logged in user. DataBinding will not work so Expression Builders is the ticket. A small source file is created, the references to web.config are shown and a simple example is built.

The Problem

I recently was looking at unanswered posts in the asp.net forum, specifically this one: http://forums.asp.net/thread/1402259.aspx. I thought I
understood how databinding and expressions worked, but just wanted to check myself. So, I made a simple example
web page just like the post shows. (see below)

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<!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 id=”Head1? runat=”server>
    <title>Untitled Page</title>
</head>
<body>
    <form id=”form1? runat=”server>
        <div>
            <asp:GridView ID=”GridView1? runat=”serverAutoGenerateColumns=”FalseDataSourceID=”SqlDataSource1?>
                <Columns>
                    <asp:BoundField DataField=”UsernameHeaderText=”UsernameSortExpression=”Username/>
                </Columns>
            </asp:GridView>
            <asp:SqlDataSource ID=”SqlDataSource1? runat=”serverConnectionString=”&lt;%$ ConnectionStrings:CodeCampSV06 %&gt;“
                SelectCommand=”SELECT [Username], [Email] FROM [Attendees] WHERE ([Username] = @Username)”>
                <SelectParameters>
                    <asp:Parameter Name=”UsernameType=”StringDefaultValue=”&lt;% User.Identity.Name %&gt;“  />
                </SelectParameters>
            </asp:SqlDataSource>
        </div>
    </form>
</body>
</html>

Then, I ran it through Lutz Roeder’s .NET Reflector and got the following from the code.


private Parameter __BuildControl__control6()
{
    Parameter parameter1 = new Parameter();
    parameter1.Name = “Username”;
    parameter1.Type = TypeCode.String;
    parameter1.DefaultValue = “<% User.Identity.Name %>”;
    return parameter1;
}

It’s pretty obvious that unless there is a username of the literal string "<% User.Identity.Name %>" no records will be find. This simply means that the build provider asp.net uses is not generating any code for us with sqldatasource that will help with the DefaultValue of parameters in a SqlDataSource.

The Solution

Expression Builder to the rescue!

To solve the problem, we need to build a simple expression builder. Without going into all the details of what an expression builder is, all you need to do is put the following code in your app_code directory and call it something like ExpressionBuilderIdentity.cs.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Compilation;
using System.CodeDom;
 
public class ExpressionBuilderIdentity : ExpressionBuilder
{
    public override System.CodeDom.CodeExpression GetCodeExpression(
        BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
    {
        CodeTypeReferenceExpression targetClass =
            new CodeTypeReferenceExpression(typeof(ExpressionBuilderIdentity));
        string targetMethod = “GetIdentity”;
        CodeExpression methodParameter =
            new CodePrimitiveExpression(entry.Expression.Trim());
        return new CodeMethodInvokeExpression(
            targetClass, targetMethod, methodParameter);
    }
 
    public static object GetIdentity(string param)
    {
        string returnString = string.Empty;
 
        if (param.ToLower().Equals(“name”))
        {
            returnString = HttpContext.Current.User.Identity.Name;
        }
 
        return returnString;
    }
}

Then, you need to add a reference to it in your web.config as follows:

<compilation debug=“true>
      <expressionBuilders>
        <add expressionPrefix=“UserIdentitytype=“ExpressionBuilderIdentity, __code/>
      </expressionBuilders>

Then, specify the SqlDataSource as follows:

<asp:SqlDataSource ID=”SqlDataSource1runat=”serverConnectionString=”&lt;%$ ConnectionStrings:CodeCampSV06 %&gt;“ SelectCommand=”SELECT [Username], [Email] FROM [Attendees] WHERE ([Username] = @Username)”>
            <SelectParameters>
                <asp:Parameter Name=”UsernameType=”StringDefaultValue=”&lt;%$ UserIdentity:name %&gt;“ />
            </SelectParameters>
        </asp:SqlDataSource>

And, Presto, it works!

Summary

Anytime you are using one of the new datasourceID controls, you need to use expressions rather than databinding if you want to reference outside variables. Creating the code is fairly straight forward and lends itself to lots of cool possibilities.

About Peter Kellner

Follow me:


Comments

  1. Why does this not work for me? I get the error: “Could not load file or assembly ‘__code’ or one of its dependencies. The system cannot find the file specified.”
    Am I doing wrong by just copying the ExpressionBuilderIdentity.cs into a folder, call it app_code and place it in the root directory of the aspx page in question (which is in the 14/TEMPLATE/LAYOUTS/ – tree)?

    Sorry, posted wrong email… ;)

  2. Why does this not work for me? I get the error: “Could not load file or assembly ‘__code’ or one of its dependencies. The system cannot find the file specified.”
    Am I doing wrong by just copying the ExpressionBuilderIdentity.cs into a folder, call it app_code and place it in the root directory of the aspx page in question (which is in the 14/TEMPLATE/LAYOUTS/ – tree)?

  3. Joshua Bredin says:

    really nice information there in your blog. Will bookmark and come back later to look for updates. Keep up the good work

  4. Interesting bit of information. Please keep writing brilliant posts like these.

  5. This is sites. I found a lot of fascinating in here. From the well written tons of comments, I can see Keep up the Thanks for the good.

  6. Thanks for detailed explanation! :)

  7. Yep, its fixed now :) Worked for me from the first try.

  8. Works like Charm!!!

    Very interesting, saved my lots of time.

    Thank You!!!

  9. Interesting… I’m going to blog about that too…

  10. phile ice cream makers reviews says:

    I wanted to thank you for this great read!! I definitely enjoying every little bit of it.I have you bookmarked to check out new stuff you post

  11. I used it today and it worked well. Only thing was the quotation marks that got changed when I copied code with Chrome.

    I agree that it open ups lots of cool avaibilites. Liked to hear more comments on any drawbacks or reason for when not to use this. Thanks anyway for your code.

  12. It worked like a charm….Thanks a lot for sharing!!!! You are the MAN!!

  13. Thank You, it’s work fine in VS but when I transferred it to real application, it’s cannot load the “_code” in web.config. Any ideas what to do next? I’m using it in the sharepoint standalone application in profile update.

  14. This is a great post for .NET developers. What all things can be done in .NET blog engine?

  15. Thanks, but I am receiving an error on your Web.Config code <expressionPrefix=

    It doesn’t like the ” before UserIdentity.

    Any ideas what might be causing this error?

  16. Thanks for detailed explanation…. nice work done

  17. Your solution is probably the best one, but in this particular situation I use a label with visible=”false” and populate it with the Identity.Name on page load. Works fine, but I’m a newb, so this approach might suck for reasons unknown to me :)

  18. Gerardo Melendrez says:

    More than a year later, but here it is the VB version of the code above:

    Imports Microsoft.VisualBasic
    Imports System.Web.Compilation
    Imports System.CodeDom

    Public Class ExpressionBuilderIdentity
    Inherits ExpressionBuilder

    Public Overrides Function GetCodeExpression(ByVal entry As System.Web.UI.BoundPropertyEntry, ByVal parsedData As Object, ByVal context As System.Web.Compilation.ExpressionBuilderContext) As System.CodeDom.CodeExpression
    Dim targetClass As New CodeTypeReferenceExpression(GetType(ExpressionBuilderIdentity))
    Dim targetMethod As String = “GetIdentity”
    Dim methodParameter As CodeExpression = New CodePrimitiveExpression(entry.Expression.Trim())
    Return New CodeMethodInvokeExpression(targetClass, targetMethod, methodParameter)
    End Function

    Public Shared Function GetIdentity(ByVal param As String) As Object
    Dim returnString As String = String.Empty
    If param.ToLower().Equals(“name”) Then
    returnString = HttpContext.Current.User.Identity.Name
    End If
    Return returnString
    End Function

    End Class

  19. Hi Peter .. Indeed a great post dude.. It really helped me as am just a beginner ..Thanks a lot

  20. I’m working with this same problem and i can’t to think there has to be an easier way. I was thinking a lot like that other kid to try and use either the cookie , control , Query String , session, … and do something like when it asked for the control parameter or somewhere. Because all i really want to do is filter a drop down box based on what their userID is.

  21. You’re post is very interesting and helpful. I am still a beginner in asp.net. Would you post the vb version of declaring the ExpressionBuilderIdentity class?

    Thanks

Follow

Get every new post delivered to your Inbox

Join other followers: