RunAt="server" (Macro)
By Kamal Patel
May 15, 2001
Background
When we drop a control such as a textbox or a label in the design area, ASP
.Net automatically adds the runat=server making it a server side control.
However, if we drop a customized control that we created, the runat=server
needs to be added explicitly. Also when adding the controls through code, we
have to type runat=server for each control. This article demonstrates how we
could write a macro for VS .Net that will use the currently open document and
add the runat=server in those elements that we specify. If the runat=server is
already defined then the macro simply ignores those elements.
Runat= Server
In order to check if controls on our page are server side controls, we have to
determine if they contain the string "runat=server" inside them. If they
contain the string, then we know that these are server side controls and if
not, then we have to add the string "runat=server" at the right position. This
program checks if specific controls are server-side controls or not and if not
then it makes them server side controls by adding runat=server.
The program is a macro written using VB and is composed of two methods. It
contains a publicly exposed method AddRunAtServer() and a private method
UpdateDocument(). UpdateDocument() receives an element as a parameter and makes
all those elements in the currently open document as server-side controls.
AddRunAtServer() is the method that makes multiple calls to UpdateDocument()
for each element that we wish to check. AddRunAtServer() is also responsible
for creating the Undo context object (discussed later) and handling errors.
The first step is to determine which elements (controls)
should be checked by this macro. By default, the macro checks all the elements
that begin with <asp:, <form, <script, and <body. You may easily
extend this functionality by adding your own elements simply by updating the
AddRunAtServer() method. If you created a library say MyLib that contains
multiple controls, you will use <MyLib:MyControl .../> syntax in your ASP
.Net pages. In order to make sure that all the controls from this library are
server side controls you will update the AddRunAtServer() method by adding:
UpdateDocument("<MyLib:")
Creating an Undo context object allows the user to undo all
the changes made by this program simply by CTRL+Z or selecting undo from the
edit menu. The code fragment below explains each line of code as we move
through the macro.
'This
macro checks the specified elements if they have runat=server in 'them
and if not then automatically adds runat=server in them Sub
AddRunAtServer()
'Create
an Undo context object so all the changes can be
'undone
by CTRL+Z
Dim
oUnDo As UndoContext =
DTE.UndoContext
oUnDo.Open("Comment
Line")
'Supress
the User Interface. This will make it run faster
'and
make all the changes appear once
DTE.SuppressUI
= True
Try
'Make
a call to UpdateDocument()
UpdateDocument("<asp:")
UpdateDocument("<form")
UpdateDocument("<script")
UpdateDocument("<body")
'Finally Close the
undo
oUnDo.Close()
Catch
oException As
system.Exception
Dim lcErrMsg As String
lcErrMsg =
"An error occured while running this program." _
&
" Please make sure that you are specifying the" _
&
" correct parameters."
MsgBox(lcErrMsg)
'Undo the changes made to the
document
oUnDo.SetAborted()
DTE.SuppressUI = False
Finally
'Rest the Supress UI
DTE.SuppressUI = False
End
Try
End
Sub
'This
method is used internally to do the actual work for adding
'runat=server
for a specified element type
Private
Sub UpdateDocument(ByVal tcStringToSearch As String)
'Get
a reference to the currently open document
Dim
oDoc As TextDocument
oDoc
= DTE.ActiveDocument.Object("TextDocument")
'Create
editpoints for starting and ending positions of the doc
Dim
lnStartPos As EditPoint =
oDoc.StartPoint.CreateEditPoint
Dim
lnEndPos As EditPoint =
oDoc.EndPoint.CreateEditPoint
'This
is the string that we will search and a placeholder string
Dim
lcSearchStr As String = tcStringToSearch
Dim
lcString As String
'Define
the private variables used in this process
Dim
lnStrPos As Integer = 0
Dim
lnRunAtPos As Integer = 0
Dim
lnClosingPos As Integer = 0
Dim
lnEmptySpot As Integer = 0
Do
While
True
'Get
the string and remove all the carriage returns as they
'are
ignored by the EditPoint object
lcString = LCase(lnStartPos.GetText(lnEndPos))
lcString = Replace(lcString, Chr(13), "")
'Get the first position of item we are
looking for
lnStrPos = InStr(lcString, lcSearchStr)
If lnStrPos = 0 Then
'If we do not find the item,
exit
Exit
Do
Else
'We found the item that we were looking
for
'Shorten the string starting from the
new position
lcString = lcString.Remove(0, lnStrPos _
+
Len(lcSearchStr))
'Now move the EditPoint to that position
as well
lnStartPos.CharRight(lnStrPos + Len(lcSearchStr))
'Now we have the subsized string, let us
check for the
'first
occurance of > is more than the runat
lnClosingPos = InStr(lcString, ">")
lnRunAtPos = InStr(lcString, "runat")
'The closing tag's position always HAS
to be more
'
than
the runat's position
If lnRunAtPos = 0 Or lnRunAtPos > lnClosingPos Then
'At this point we found that
Runat=server is
'
missing
in this element/object
'Locate the first blank spot to make the
insertion.
lnEmptySpot = InStr(lcString, " ")
'Make sure that the blank spot is within
the
'boundries
If lnEmptySpot > lnClosingPos
Then
'Special handling
required
'In this case we want to place just
before
'
the
closing position i.e. ">"
'However, it is possible that the
closing is
'
done
using />
If lcString.Substring(lnClosingPos
- 2, 1) = _
"/"
Then
lnStartPos.CharRight(lnClosingPos - 2)
lnStartPos.Insert(" ")
Else
lnStartPos.CharRight(lnClosingPos - 1)
lnStartPos.Insert("
")
End
If
Else
lnStartPos.CharRight(lnEmptySpot)
End
If
'Once the blank spot is determined and
the
'
EditPoint
is positioned, Make the insertion
lnStartPos.Insert("runat=server ")
End
If
End
If
Loop
End
Sub
|