cschear
cschear

Reputation: 379

Make Sure UserControl Is Included Only Once

We currently have all of our tracking / analytic code in a usercontrol (ascx). We like this because, using our CMS, we can just drop the control on any page that needs tracking.

The issue is now it is possible for a user to inadvertently drop a control on a page that may already have it included. For example : We include the control on a master page - then again on a page that inherits from this master.

What would be the best way to insure the user control is used only once when rendering the page?

Upvotes: 1

Views: 318

Answers (5)

theoretical
theoretical

Reputation: 420

The HttpContext class has an Items collection that you can write to and read from that lives as long as the current request is being processed. If you're just dropping the control onto the page, the only thing you could do is have the control itself check to see if it's been loaded by setting a flag in the HttpContext.Current.Items collection and if it's already been loaded, don't render the output. If you want to be smart about only loading once, you can, instead of dropping the control onto the page, write a helper/static method for loading the control (say into a placeholder control that the devs drop onto the page). The helper method can then use HttpContext to determine whether or not to load the control.

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460058

There is no way than to loop all controls and their parents/childs.

For example:

Public Module ExtensionMethods

    <Runtime.CompilerServices.Extension()> _
    Public Function FindControlRecursively(ByVal parentControl As System.Web.UI.Control, ByVal controlType As Type) As System.Web.UI.Control

        If parentControl.GetType = controlType Then
            Return parentControl
        End If

        For Each c As System.Web.UI.Control In parentControl.Controls
            Dim child As System.Web.UI.Control = FindControlRecursively(c, controlType)
            If child IsNot Nothing Then
                Return child
            End If
        Next

        Return Nothing

    End Function

End Module

and you can check it so:

If Not FindControlRecursively(Me.Page.Master, GetType(UC_Status)) Is Nothing Then
   'thow exception or whatever'
End If

Note: all untested

Upvotes: 1

Gregory A Beamer
Gregory A Beamer

Reputation: 17010

Since this is a design time issue, there is not much you can do other than test the page it is added to before deploying again.

If this is done runtime, you can iterate the controls and look for the same type. Remove if found.

Upvotes: 0

StriplingWarrior
StriplingWarrior

Reputation: 156459

It depends largely on the composition of your team. For many teams, the "best" way would simply be to adopt a policy of only including the control on Master Pages.

There are more technical solutions, if you can't trust your developers to follow this rule, though. For example, the control could set a per-request flag when it is rendered, and check that flag each time to make sure it's not already been rendered on that request. If it's already been rendered on the given request, it simply won't re-render.

Upvotes: 2

ek_ny
ek_ny

Reputation: 10243

you could probably loop over the controls on the page when adding it. If it exists, then don't add it.

Upvotes: 0

Related Questions