More Fun With LINQ - Perform Common Tasks in ASP.NET

Posted by: Malcolm Sheridan , on 7/24/2009, in Category LINQ
Views: 40381
Abstract: The following article demonstrates how to use LINQ to perform some complex tasks in ASP.NET.
More Fun With LINQ - Perform Common Tasks in ASP.NET
 
Earlier this year Suprotim Agarwal did one article on Fun with LINQ. I was recently asked a question in a forum on how to find all the text boxes in an ASP.NET page. I said use LINQ! It is a perfect solution for this! So I thought I’d write a small article on how to do this plus another LINQ query that I have used in the past that is quite handy.
Open Visual Studio 2008 and choose File > New > Web > ASP.NET Web Application. We’ll use this web application to run all these examples. Open the Default.aspx page and add the following controls:
 
<form id="form12" runat="server">
    <asp:Panel ID="Panel1" runat="server">
        <asp:TextBox ID="txtOne" runat="server"></asp:TextBox><asp:RequiredFieldValidator
            ID="RequiredFieldValidator1" runat="server"
            ErrorMessage="text 1 is required" ControlToValidate="txtOne"></asp:RequiredFieldValidator>
        <br />
        <asp:TextBox ID="txtTwo" runat="server"></asp:TextBox>
        <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
            ControlToValidate="txtTwo" Display="Dynamic"
            ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
        <br />
        <br />
        <asp:TextBox ID="txtThree" runat="server" Enabled="true"></asp:TextBox>
        <br />
    </asp:Panel>
   <asp:DropDownList ID="DropDownList1" runat="server">
        <asp:ListItem>short</asp:ListItem>
        <asp:ListItem>longer</asp:ListItem>
        <asp:ListItem Value="1">this is some really long text!!!!</asp:ListItem>
        <asp:ListItem Value="2">hopefull this gets seen too!!!</asp:ListItem>
    </asp:DropDownList></form>
The mark-up above will be used in all the examples.
Find every enabled TextBox on an ASP.NET page
 
As you can see there are three text box controls on the page. They’re located inside a panel, so to get to these controls you need to write a recursive function because the text box’s parent is the Panel control, and that is a child control on the Page. So the following code can be used to get every enabled text box:
 
C#
 
private int Count { get; set; } 
protected void Page_Load(object sender, EventArgs e)
{           
GetControl(this);           
}
 
private void GetControl(Control parent)
{  
            Count += (from p in parent.Controls.Cast<Control>()
                      let txt = p as TextBox
                      where (txt != null && txt.Enabled)
                      select p).Count();          
 
            foreach (Control item in parent.Controls)
            {
                if (item.Controls.Count > 0)
                {
                    GetControl(item);                  
                }               
            }
}
 
VB.NET
 
Private privateCount As Integer
Private Property Count() As Integer
      Get
            Return privateCount
      End Get
      Set(ByVal value As Integer)
            privateCount = value
      End Set
End Property
 
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
GetControl(Me)
End Sub
 
Private Sub GetControl(ByVal parent As Control)
                  Count += ( _
                      From p In parent.Controls.Cast(Of Control)() _
                      Let txt = TryCast(p, TextBox) _
                      Where (txt IsNot Nothing AndAlso txt.Enabled) _
                      Select p).Count()
 
                  For Each item As Control In parent.Controls
                        If item.Controls.Count > 0 Then
                              GetControl(item)
                        End If
                  Next item
End Sub
Find long items in an ASP.NET DropDownList
 
This example will find any DropDownList control and search through the items to see which item has a text property that is longer than 10 characters and return a count:
 
C#
 
private void FindDropDownControl(Control parent)
{
            Count += (from p in parent.Controls.Cast<Control>()
                      let txt = p as DropDownList
                      where (txt != null && txt.Items.Cast<ListItem>().Any(o => o.Text.Length > 10))
                      select p).Count();
 
            foreach (Control item in parent.Controls)
            {
                if (item.Controls.Count > 0)
                {
                    GetControl(item);
                }
            }
}
 
VB.NET
 
Private Sub FindDropDownControl(ByVal parent As Control)
                  Count += ( _
                      From p In parent.Controls.Cast(Of Control)() _
                      Let txt = TryCast(p, DropDownList) _
                      Where (txt IsNot Nothing AndAlso txt.Items.Cast(Of ListItem)().Any(Function(o) o.Text.Length > 10)) _
                      Select p).Count()
 
                  For Each item As Control In parent.Controls
                        If item.Controls.Count > 0 Then
                              GetControl(item)
                        End If
                  Next item
End Sub
 
And if you need to display the actual ListItems, you can use this query:
 
C#
 
private static void FindDropDownListAll(Control parent)
{
            var query = (from p in parent.Controls.Cast<Control>()
                         let txt = p as DropDownList
                         where (txt != null && txt.Items.Cast<ListItem>().Any(o => o.Text.Length > 10))
                         select new
                         {
                             Name = p.ClientID,
                             Items = txt.Items.Cast<ListItem>().Where(o => o.Text.Length > 10).ToList()
                         });
 
            foreach (var item in query)
            {
                List<ListItem> txt = item.Items;
            }
}
 
VB.NET
 
Private Shared Sub FindDropDownListAll(ByVal parent As Control)
                  Dim query = ( _
                      From p In parent.Controls.Cast(Of Control)() _
                      Let txt = TryCast(p, DropDownList) _
                      Where (txt IsNot Nothing AndAlso txt.Items.Cast(Of ListItem)().Any(Function(o) o.Text.Length > 10)) _
                      Select New With {Key .Name = p.ClientID, Key .Items = txt.Items.Cast(Of ListItem)().Where(Function(o) o.Text.Length > 10).ToList()})
 
                  For Each item In query
                        Dim txt As List(Of ListItem) = item.Items
                  Next item
End Sub
 

Hopefully these examples have given you another reason as to why LINQ is cool!

The entire source code of this article can be downloaded over here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by John Bubriski on Friday, July 24, 2009 9:26 AM
Nice article!  Good creative use of LINQ!
Comment posted by Corey Magin on Monday, July 27, 2009 9:33 AM
For some reason I get excited when I see new uses for linq.  Thanks for the article, helps me learn more about linq and it's uses.
Comment posted by Jerome Laban on Monday, July 27, 2009 3:10 PM
Why do you use Cast<> instead of OfType<> ? That would avoid the use of TryCast method...
Comment posted by Malcolm Sheridan on Monday, July 27, 2009 7:53 PM
@Jerome
I've never used OfType but I'll give it a try.  Thanks for the tip!
Comment posted by Franklin Davis on Tuesday, July 28, 2009 3:25 PM
How about one that doesn't require a private class variable?

private int NumberOfEnabledTextBoxes(Control parentControl)
        {
            Func<Control, IEnumerable<Control>> childControls = null;

            childControls = (control) => control.Controls
                .Cast<Control>()
                .Concat(
                    control.Controls
                    .Cast<Control>()
                    .SelectMany(child => childControls(child))
                    );

            return childControls(parentControl)
                .OfType<TextBox>()
                .Where(txt => txt.Enabled)
                .Count();  
                
        }
Comment posted by Malcolm Sheridan on Thursday, July 30, 2009 7:55 PM
@Franklin
I haven't tested it but if it works that is great work!
Comment posted by James Curran on Tuesday, August 4, 2009 12:44 PM
Here's my take on it.

private static int  NumberOfEnabledTextBoxes(Control parent)
{
    int count =
        parent.Controls.OfType<TextBox>()
                       .Where(txt => txt.Enabled)
                       .Count();

    count += parent.Controls.Cast<Control>()
                   .Where(ctrl => ctrl.Controls.Count > 0)
                   .Sum(ctrl => NumberOfEnabledTextBoxes(ctrl));

    return count;
}
Comment posted by Thanigainathan on Thursday, October 1, 2009 2:29 AM
Hi There,

Nice article.
So you mean this will be performing good compared to traditional coding ?
Definitely we will be having no of lines reduced.

Thanks,
Thani
Comment posted by Malcolm Sheridan on Thursday, October 1, 2009 6:58 AM
@Thanigainathan
I don't know about it performing better, but it does reduce the lines of code required.  Plus you get to use LINQ!
Comment posted by tuturutu on Thursday, October 1, 2009 10:46 AM
Cool article!!!
Comment posted by kemal on Sunday, November 1, 2009 10:42 PM
plz brother send me teh code for LINQ.  URGENT.