Tag Archives: .NET
Identify on a single layer in the Web Mapping Application
Robert Burke, an instructor for ESRI Educational Services and author of Getting to Know ArcObjects, contributed the following post.
In teaching ArcGIS Server developers over the last few months, one question I
often get is, “How can I change the Identify tool to work on just one
layer?” For example, my published map service has 40 layers on it, but I only
need my users to identify one or a few of the layers.
These instructions are for a Web Mapping Application created with ArcGIS Server
for the Microsoft .NET Framework. It can be an application created in Manager,
or one created with Visual Studio 2005.
First, you have a published map service and need to know the order of layers in
that map service. Use ArcMap to open the map document (the MXD or PMF file) for
the service in question and list the layers in the map’s published data frame.
Here my data frame has the default name, called Layers, and contains five
layers, but two are in a group layer called Buffer Points.
Layers
Buffer Points
InputFeatures point layer
Output Feature Class
Streets
CityLimit
Parcels
Now determine the index position of these layers in the MXD file. I have a group
layer, so that influences the index numbers for each layer. Normally the top
layer is index 0, the one under it Index 1, the one under that 2, and so on.
But with a group layer, the entry for the group gets an index and then layers
in the group each have their own index numbers. Identify can use these index
numbers when looking for features to be identified. The numbering for my layers
is as follows.
Layers
(0) Buffer Points
(1) InputFeatures point layer
(2) Output Feature Class
(3) Streets
(4) CityLimit
(5) Parcels
Layers gets no index position because it is not a layer, it’s just a data frame.
Now that you know the layer index numbers, you are ready to go to the code for
the Identify tool. Use Visual Studio 2005 (or Visual Web Developer Express,
free download from Microsoft) to open the Web Mapping Application
website you want to modify. In the website, open the MapIdentify.vb or
MapIdentify.cs code file in the project’s App_Code folder. In the code, locate
the Identify function.
[VB]
Public Function Identify(ByVal queryString As NameValueCollection) As String
[C#]
public string Identify(NameValueCollection queryString)
Scroll down to about the midpoint of the Identify function and locate the
following lines of code.
[VB]
Dim ds As DataTable() = Nothing
Try
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, Nothing)
[C#]
DataTable[] ds = null;
try
{
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, null);
After the first line with the DataTable, and before the Try statement, add in an
extra line of code. As shown below, the new line creates a one-dimensional
string array variable and immediately adds two string values to it. Here the 3
and 5 represent the index positions of layers in the map, Streets and Parcels.
Here we are altering the Identify tool to select features from just these two
layers. You have one more step before testing the tool.
[VB]
Dim ds As DataTable() = Nothing
Dim lids() As String = {"3", "5"}
Try
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, Nothing)
[C#]
DataTable[] ds = null;
string[] lids = { "3", "5" };
try
{
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, null);
On the last line of code, the Identify method is being used on the map’s
QueryFunctionality. The method has 5 arguments; the last argument represents a
string array of the layers that you would like to identify. In this case
however, the keyword Nothing (null) is currently in place. When Nothing (null)
is passed here, the identify works with all layers.
The first argument on the Identify method is name of the map functionality. The
second argument for Identify represents the point where the user clicked on the
map. If you look above in the code you will see that the initial point is
returned in screen pixel units and is then converted into map units. The third
argument represents a tolerance number in pixels. This is the search distance
used by Identify from the point where the user clicked. A pseudo-buffer zone is
created x number of pixels around that point. The tolerance is an integer, so
if you have a 3 in there, a search will be made using a three-pixel buffer
around the user point. The fourth argument has three possible Identify option
values: AllLayers, VisibleLayers, and TopMostLayer. The Identify method uses
the VisibleLayers choice.
In the Identify method, replace the Nothing (null) keyword with the String
Array you created above.
[VB]
Dim ds As DataTable() = Nothing
Dim lids() As String = {"3", "5"}
Try
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, lids)
[C#]
DataTable[] ds = null;
string[] lids = { "3", "5" };
try
{
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, lids);
You can now run the application and test the Identify tool. Provided you have
layers at index positions 3 and 5, the tool will only work with features from
those two layers and ignore the others.
Now if you just want to identify the Streets layer, just alter the array
definition and only include one layer index number. In this example Streets is
at index position 3 so you will omit the 5 for the Parcels layer.
[VB]
Dim ds As DataTable() = Nothing
Dim lids() As String = {"3"}
Try
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, lids)
[C#]
DataTable[] ds = null;
string[] lids = { "3" };
try
{
ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, lids);
If you run the code above, only features from the Streets layer will be
identified and the other layers will be ignored.
EditorTask customization guide and sample
In this post, Rex Hansen describes how to customize the .NET Web ADF EditorTask control and provides a downloadable sample.
While the EditorTask includes a comprehensive set of out-of-the-box capabilities, many Web editing solutions require customizing the behavior of the EditorTask to satisfy user specific requirements. The EditorTask offers two options for developing a custom solution:
- Using the out-of-the-box EditorTask, add custom functionality by handling EditorTask events in a page.
- Create a custom Web control by subclassing the EditorTask and its child controls.
Option 1 is designed for convenient access to standard EditorTask events in a Web application. Option 2 is more complex, but provides comprehensive access to the implementation details (which includes events) of the EditorTask and its subcomponents. It also enables you to package a Web ADF editing solution as a redistributable custom EditorTask control. In either case, it is important to understand the existing structure of an EditorTask. At run-time the EditorTask creates two visible container controls: the Editor and EditorSettingsPanel. The Editor is a composite control that contains either a VersionIDPanel or a set of editor panels and other controls to edit feature layers. The EditorSettingsPanel is a type of EditorPanel that contains a SnappingPanel and SelectionPanel. The class type and naming of these components will be important when working with EditorTask events or subclassing them in a custom EditorTask control.
Panel Structure and Naming
This section provides a visual guide to the class type and unique control id for notable components packaged with the EditorTask. For each component, the class type is listed above the unique control id, listed in quotes.
If an editable layer is versioned and more than one version is available for editing, the VersionIDPanel will be displayed in the Editor when the EditorTask is initialized at runtime.
The EditorTask contains an Editor which represents the primary visible control that contains other editing controls. The Editor contains a drop down list to select an editable layer. The main toolbar contains a set of tools and commands to manage the selected features in the active edit layer. A set of commands to manage edit operations may be included depending on the type of layer being edited and the map service in which it is accessed. When editing a non-versioned feature layer in a pooled service, the main toolbar will not contain an Undo, Redo, or Save button. When editing non-versioned data in a non-pooled service, the Undo and Redo buttons will not be available (the Save button will be available). The main toolbar can be customized.
The Editor also contains a set of panels to create and modify features and attributes. The CreateFeaturePanel contains one or more tools to create a new feature depending on the active edit layer feature type. It contains a toolbar that cannot be customized. The EditExistingFeaturesPanel contains a number of tools and commands to modify existing features, packaged in two toolbars; GeometryToolbar1 contains items to modify entire features while items in GeometryToolbar2 were designed to manipulate feature vertices. Both toolbars can be customized. The EditAttributesPanel lists the attributes of the current set of selected features. Since only one feature’s attributes can be visible at any time, paging will be enabled when more than one feature is selected. The visibility and editability of attributes can be modified via attribute filtering. The attribute labels and textboxes are generated internally by the EditAttributesPanel and are not available for explicit customization.
The EditorTask also contains an EditorSettingsPanel which can be initialized via the Editor at runtime and is designed to compliment actions initiated by Editor panels. The EditorSettingsPanel contains two panels: a SnappingPanel and SelectionPanel. The SnappingPanel panel provides the ability to change snapping rules and snap tips display at runtime. The SelectionPanel provides the end user with the ability to modify selection behavior when using the select tool in the Editor’s main toolbar. Both panels are not designed to be customized. However, like the Editor, the EditorSettingsPanel is designed to allow the addition and/or removal of panels.
Customization Categories
The EditorTask was explicitly designed to support customization in the following distinct, but related categories:
- EditorTask events
- Attribute Filtering
- Custom Editor Tools
- Custom Editor Panels
Recall that there are two options for developing a custom EditorTask solution; handle events on an out-of-the-box EditorTask control or subclass the EditorTask and its subcomponents. Both options are demonstrated in the example provided, within the context of each category.
Option 1 uses an out-of-the-box EditorTask control and EditorTask events within the context of the pagecontrol lifecycle to implement custom capabilities in each category. The diagram below highlights where these categories can be leveraged with Option 1. Note that you can add event handlers during Page or EditorTask control lifecycle events (e.g Init, Load).
Option 2 demonstrates how to subclass existing EditorTask controls, override members, create new custom components, and construct a redistributable EditorTask component. All customization capabilities present in Option 1 are available with Option 2, plus those capabilities that are only available within a subclass solution (e.g. protected members). The diagram below highlights where the implementation of each customization category may occur when extending the EditorTask.

What’s in the sample
To get the sample, download one of the following based on your preference for C# or VB.NET:
Two projects are packaged with the sample:
-
A class library project (CustomEditorTask_<language>) that contains the classes and content needed to create a custom EditorTask control. Note the following customizations:
- On initial load of the custom EditorTask, attributes for the “Tentative Assessed Parcels”, “Address Points” and “Water Bodies” layers are filtered for display.
- On post tool execute, if a feature was created or modified in the “Tentative Assessed Parcels” layer, the time of the edit is written to respective fields in the feature class.
- The EditExistingFeaturePanel has been replaced by a custom Editor panel. The custom panel subclasses EditExistingFeaturePanel and adds two custom Editor tools, clip features and convert polygon to polyline.
- A set of custom properties on the EditorTask define if map units should be used for snapping. If true, a custom EditorSettingsPanel replaces the existing default panel. The custom panel also contains a custom SnappingPanel which contains the logic necessary to snap using map units (pixel tolerance changes with map scale).
-
A Web project (CustomEditorTaskWebApp_<language>) that contains two pages and a set of custom components (Editor tools and panels) in the App_Code folder. One page includes a reference to the custom EditorTask control created in the aforementioned project. The other page contains an out-of-the-box Editor task which is customized by handling events on the EditorTask. Both pages handle the release of server context for non-pooled services via a callback when the browser is closed. Note the following customizations to the out-of-the-box EditorTask:
- On initial load of the page, attributes for the “Tentative Assessed Parcels”, “Address Points” and “Water Bodies” layers are filtered for display and applied to the EditorTask.
- A custom CreateFeaturePanel is added to the Editor. It contains a custom tool that references the prepackaged CreateFeature EditorToolServerAction.
- A custom clip Editor tool is added to the existing GeometryToolbar1 in the EditExistingFeaturePanel.
- A custom Editor toolbar and custom Editor command is added to the EditExistingFeaturePanel.
- On pre attribute update, if a field named “UPDATEDBY” exists in the active edit layer and an authenticated user has been defined, add the username as a field value.
- On post attribute update, if update was not successful, return the exception message in an alert box.
- On pre command execute, cancel actions that delete features in the “Address Points” layer.
How to set up the sample
This section explains how to set up the sample after you have downloaded the two projects mentioned above. Before you begin, unzip the Common_CustomEditorTask_<language> zip file into a folder accessible from IIS (e.g. c:inetpubwwwroot).
Set up access to the geodatabase
You must have access to Microsoft SQL Server Express which has been configured for use with ArcSDE Workgroup geodatabases to use the data packaged with the sample. If you use your own data, you will need to change some portions of the sample code to function.
- Assuming you have access to SQL Server Express configured for use with ArcSDE Workgroup geodatabases, open ArcCatalog; under Database Servers click Add Database Server and connect to SQL Server Express.
- Right-click on the SQL Server Express instance and select Permissions. Add the ArcGIS Server container account.
- Right-click the SQL Server Express instance and select Attach. Navigate to the EditParcels.mdf included with the sample (e.g. c:inetpubwwwrootCommon_ CustomEditorTask _CSharpdataEditParcels.mdf). The EditParcels geodatabase should be added to the geodatabase list for the SQL Server Express instance in ArcCatalog.
- Right-click on the EditParcels geodatabase and select Administration>Permissions. Grant the ArcGIS Server container account readwrite privileges.
Configure the map document and create the map service
- Open the EditParcelsDemo.mxd in ArcMap. Note that the data source for every layer is invalid, thus a red exclamation point is displayed next to each layer name. Click (single left mouse button click) on the red exclamation point next to the “Address Points” layer to display the Set Data Source dialog.

- Navigate to the SQL Server Express instance on which the EditParcels geodatabase is available. Select the “EditParcels.DBO.AddressPoints” feature class and select OK. Data sources for all layers in the map document should be repaired. Save the map document. ArcMap should appear as follows.

-
Open ArcCatalog and add a new map service with the following properties:
Name: EditParcelsDemo
Map document: <path to EditParcelsDemo.mxd>
Pooling: Not Pooled, Min instances: 0, Max instances 6When finished, start the service.
Configure the EditorTask projects
- Open the IIS Manager from Control Panel > Administrative Tools > Internet Information Services (IIS) Manager or Internet Information Services
- In the console tree view on the left, navigate to Local Computer > Web Sites > Default Web Site.
- Open the Common_ CustomEditorTask _<language> folder, right-click the CustomEditorTaskWebApp_<language> folder and click Properties.
- On the Directory tab, click the Create button in the Application Settings section of this panel. Click OK to dismiss the Properties dialog.
- Launch Microsoft Visual Studio 2005 and open the Common_ CustomEditorTask _<language> solution located where you unzipped the file in step 1. (e.g. c:inetpubwwwrootCommon_ CustomEditorTask _CSharpCommon_CustomEditorTask _CSharp.sln).
- In the Solution Explorer, right-click the CustomEditorTaskWebApp _<language> project and select ‘Set as StartUp Project’. Also, right-click CustomEditorTaskPage.aspx and select ‘Set As Start Page’.
- If necessary, set an impersonation identity for the Web application. Right-click on the Web project and select “Add ArcGIS Identity”. Enter the credentials of a user account which has been added to the agsadmin or agsusers group on the SOM (server object manager) where the EditParcelsDemo map service is running.
- Open the CustomEditorTaskPage.aspx in design view and define the connection properties for the single ArcGIS Server Local map resource item in the MapResourceManager.
- Also in design-view, set CustomEditorTask1 control properties to define the map and resource, editable layers (select all) and editable versions (select all).
- Open the StandardEditorTaskPage.aspx and modify the MapResourceManager and EditorTask1 using the same properties defined in the CustomEditorTaskPage.aspx.
- Build the solution. View both Web pages in a browser and use the EditorTask at runtime. The following screenshot shows the CustomEditorTaskPage.aspx at runtime:

Displaying task results in a table
In this post, Tom Brenneman of ESRI Professional Services presents a Web control he developed for displaying task results in a table.
The standard Web ADF controls render task results with a tree view. This is allows multiple results as well as a variety of result types to be displayed in a uniform way. However some applications require that task results be displayed in a table without having to navigate the tree structure of the standard task results. There is an existing sample that illustrates how this can be done by working with custom tasks or application logic that dynamically updates an ASP.NET GridView control.
The custom control I’ve provided in this post is a little different in that it works with both standard tasks and custom tasks. Using this GridResults control, you can display the results of a task in a grid by simply adding the GridResults as a Task Result Container of the task. The table generated by the GridResults control also includes rows with buttons and check boxes to enable Pan, Zoom, and Select for each feature. This is what the GridResults control looks like in a web application:
As you can see in the example there are also links at the top to you can Select, Unselect, and Zoom to all of the features in the table. By clicking on the column headers you can sort data in the table. What you can’t see in the example above is that this control also supports ASP.NET themes, so you have complete control over the colors, fonts, and text sizes used by the control. Implementing themes for the control is discussed in more detail at the end of this post.
If you are using the Web Mapping Application template, there are slightly different ways to configure the grid than if you are using it in a standard web page. Below are instructions for each approach.
Using the GridResults control in a Web Mapping Application template application
- Install the GridResults web control.
- Using Visual Studio, create a new website using the Web Mapping Application template.
- Right-click anywhere on the Toolbox and click Choose Items…
- Click Browse and Navigate to gridResults.dll (Default location is C:Program FilesESRIArcGIS GridResults Control).
- Click OK to dismiss the Choose Toolbox Items dialog.
- Open the Source view for Default.aspx.
- Find the Results floating panel at about line 98. Highlight this block and copy it, then paste it immediately below. We are doing this with the Source view so you can be sure that the location you paste the floating panel is still in the left panel div with the rest of the floating panels. You also may want to keep the Results panel and standard task results container “TaskResults1″ for tools such as Identify.
- Change the Title property of the new floating panel to “Table Results”.
- Delete the entire TaskResults tag (TaskResults2) from the new Table Results panel.
-
Drag gridResults from the Toolbox into the Table Results floating panel (Where the taskResults control used to exist). Your markup should look like the following.
<esri:FloatingPanel ID="FloatingPanel1" runat="server"
BackColor="White" BorderColor="White" BorderStyle="Solid"
BorderWidth="1px" Font-Names="Verdana" Font-Size="8pt"
ForeColor="Black" Height="150px" Style="position:relative; margin
bottom:0px;" Draggable="False" Title="Table Results"
TitleBarColor="White" TitleBarHeight="20px"
TitleBarSeparatorLine="True" Transparency="0" Width="100%"
HeightResizable="True" Font-Bold="True" CloseButton="False"
TitleBarForeColor="DarkGray" Expanded="False"
WidthResizable="False" ShowDockButton="True"
ShowDockedContextMenu="True">
<esri_samples:gridResults ID="GridResults1" runat="server"
Height="200px" Style="position: absolute; overflow: auto;"
Visible="True" Width="400px" />
</esri:FloatingPanel> -
To make the grid display with scroll bars in the floating panel, we need to adjust the style attribute of the control. Change the style attribute to the following.
Style="position:absolute; height:100%; width:100%; overflow:auto; left:0px; top:0px;"
- Switch to design view.
- Right-click on GridResults1 and click Properties.
- Set the Map property of the GridResults1 to the name of your map (Map1).
- Use the MapResourceManager to add a map resource to the application.
- Add tasks (such as QueryAttributesTask) to the task manager and configure their properties.
- Click the Smart Tag on your task(s) and click Choose Task Results container.
- Click Add and set the Name of the Buddy Control to GridResults1. If you use the standard TaskResults control with your tasks as well, make sure the standard TaskResults is the last one in the list.
- Click OK to the BuddyControl Collection Editor and run the application.
- When you execute the task, the floating panel will update with a table containing the results.
Using the GridResults control without a floating panel
Use the instructions below if you have created a web application without the Web Mapping Application template. In this case, you will set the style properties appropriately for your application.
- Open your web application in Visual Studio.
- Do steps 3-5 in the instructions from the previous section.
- Add the GridResults control to your page.
- Set the Map and other properties of the GridResults to display appropriately in your application. In the sample I use the following property settings.
<esri_samples:gridResults ID="GridResults1" runat="server" Height="290px" Visible="True" Width="780px" Map="Map1" Style="position:absolute; overflow:auto; z-index: 500; left: 20px; top: 450px; vertical-align:top;" MinWidthOfZoom="0.001" />
- Do steps 15-20 in the instructions from the previous section.
Common properties of the GridResults control to modify
There are two additional properties that you may want to change specifically for your application: MinWidthOfZoom and ZoomExtentExpansionPercentage.
- MinWidthOfZoom – this is the minimum width (or height actually) in map units of the extent rectangle that will be zoomed to. This is particularly useful if the result set is a single point or a very small feature. In this case you could set the minimum extent that the map will zoom to. If you are working with geographic data you may want to make this significantly smaller than the default of 10.
- ZoomExtentExpansionPercent – this is the expansion percentage around the extent of the result set for the map to zoom to. This is useful for defining a margin around the extent of features returned in a result set.
Controlling the appearance of the results control with skins
The GridResults control is actually a Panel control containing a Label control (the resulting table name), Hyperlink controls (The zoom to all button, pan to all button, etc.), and a GridView control. The appearance of these controls honors the styleSheetTheme of your application. Using ASP.NET themes and skins you can control the look and feel of this control in your application. The following are the set of steps to enable themes and configure a skin for the table in the GridResults control. This example modifies the Blue_Bridge theme used by the Web Mapping Application template. If you aren’t using the Web Mapping Application template, you will have to create an appropriate theme for your application before walking through these steps.
- Enable style sheet themes by adding the following tag to your Web.config file.
<pages styleSheetTheme="Blue_Bridge"/>
If you are using the Web Mapping Application template you will want to leave the theme attribute as well, so your tag should look like this.
<pages theme="Blue_Bridge" styleSheetTheme="Blue_Bridge"/>
- Open App_themes > Blue_Bridge > Default.skin.
-
Add the appropriate tags to control the appearance of the Label, Hyperlink, and GridView controls contained within this control. Below is an example tag to make the symbology of the grid similar to the Blue_Bridge theme. You can copy and paste this into your skin file as an example.
<asp:GridView runat="server" BackColor="White" BorderColor="#999999"
BorderStyle="None" BorderWidth="1px" CellPadding="3" GridLines="Vertical">
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<RowStyle BackColor="White" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<HeaderStyle BackColor="#79A8D1" Font-Bold="True" ForeColor="Black"/>
<AlternatingRowStyle BackColor="#C0D4E4" />
</asp:GridView> - Save and run the application. When you execute the task, you should now see the results displayed in the table with a light blue header and a blue background for the alternating item (See the graphic at the top of this post for an example).
Try it out
- For an example of the GridResults control in action, see this sample application.
- You can download the control and try it out. An installer has been included for convenience.
- You can also download the source code used to create this control and customize it any way you like.
Note: This control and its source code are provided for example purposes only and do not constitute a supported ESRI product. Please direct questions about this control to the Comments section of this blog. You may also post questions about using the ArcGIS Server Web ADF to the ESRI User Forums.
Update (February 26, 2008): I fixed a problem with the GridResults control where sorting didn’t work right when there are multiple results. This problem is most evident when you use the GridResults control with the Identify tool. This new control is available on ArcScripts here: http://arcscripts.esri.com/details.asp?dbid=15452 .
Security techniques for .NET Web ADF applications
In this post, Bryan Baker describes a new security sample he contributed to EDN:
A new developer sample that demonstrates security techniques for the Web ADF is available at the ESRI Developer Network. This sample will also be available as part of the installed software developer kit (SDK) samples with the next service pack of ArcGIS Server.
This sample shows some ways to restrict access to GIS resources and functionality based on the user’s login. While access may be restricted in a variety of ways, the sample takes this approach:
- All users must log in before they can access the web application. Users are redirected to a login page to log in.
- Once logged in, users see the main website page with map, table of contents, etc. This sample uses a simple set of web controls rather than the full Web Mapping Application template, but the same techniques could be applied to the template.
- Content varies depending on the role (group) in which the user is a member. This sample has a Managers role. Users in this role see all content added to the web application. If the user is not in this role, the following content is hidden:
- A map layer (highways) is hidden and its entry is removed from the table of contents.
- An item is removed from the toolbar. This item is a command that displays information about map layers and fields.
- Two query tasks are removed from the page.
- ASP.NET controls are used to display the user’s login name, and to display hyperlinks to log out, to change the user’s password, and to create a new account from the login page.
The upcoming version 9.3 of ArcGIS Server will feature out-of-the-box security in ArcGIS Server Manager. Those features will enable you to require users to log in to access services or web applications. However, those will not include the ability to restrict access to specific functionality and layers within a web application, based on the identity of the user. So the techniques in this sample will be relevant for both 9.2 and 9.3.
The introduction page to the sample at EDN contains more information on the sample. Standard ASP.NET techniques provided the functionality for all of the security aspects of the sample. Note that this sample is limited to restrict content to authorized users. It does not cover other aspects of security, such as encrypting traffic between user and server using secure sockets layer (SSL, using HTTPS), or checking user input for invalid values. Many websites have information about these other important aspects of securing web applications.
Some details on the sample
For those of you who might be interested, read on for some discussion of how security is implemented in this sample. First we cover how we require all users to log in in order to access the site. Then we’ll see how resources and functionality differ depending on who the user is.
Require users to log in
We require all users to log in in order to access the application. We could set this up manually in code, but a built-in tool makes it easier: the Web Site Administration Tool (WSAT). This ASP.NET tool is available from Visual Studio (or Visual Web Developer Express). After we open the website for which we want to set security, we can open WSAT from Visual Studio’s Website menu. This web-based administrative tool allows us to set up and manage security for our web application.
In the main WSAT menu, we choose Security.
WSAT displays two options for access: from the Internet and from a local network. These translate into where the users are stored. The local-network option means users are Windows users on the local server or on the domain. This option also typically means that users visiting the site will be prompted for their login by a pop-up dialog in the browser. While the local-network option is the default when creating a new ASP.NET web application, most websites use the second option (“from the Internet”), which means users are stored in a database or other external location. This way we can provide the typical web page form that users fill out to log in. Behind the scenes, this choice sets an authentication element in the web.config file of the website:
<authentication mode="Forms" />
Also behind the scenes, setting the authentication type sets up a database within our web application. By default, WSAT creates a SQL Server Express database within the App_Data folder of our website. This database is specific to this web application. It is possible to use a database outside the web application, including a database in the full SQL Server or another database. See documentation or websites on ASP.NET for information. For our sample, we use the default application-level database.
Once we choose our authentication type, we see the web page that allows us to manage the access security for our site.
We will not go through the steps individually here, but we used this page to create our users, enable roles, add roles, and assign users to roles. Roles allow us to manage security without adding or removing users individually to access rules when people enter or leave the organization or change positions within the organization. All these users and roles are stored in our SQL Server Express database.
Finally in WSAT, we create access rules for our website. These rules determine who can access our website. We used a simple rule: anyone can obtain access to the website as long as they have a user account. All we need to do is to prevent access by anonymous users. We do that by clicking the Create access rules hyperlink, and in the add-access-rule page, we select Anonymous users, ensure that “Deny” is selected, and click OK.
Again behind the scenes, this adds an authorization element to the web.config file of the web application:
<authorization>
<deny users="?" />
</authorization>
This element instructs the application to not allow anonymous users (indicated by the “?”) to access the website.
Now our application will require users to log in, and it will get their login from a form. We just need to provide the form for logging in. Fortunately, ASP.NET 2.0 (and above) makes this easy. We just create a new page within the website and name it login.aspx. By default, ASP.NET will look for this page and use it. In Visual Studio, we drag a Login web control onto this login.aspx page, and save it. That’s all that’s required to create a login page, though we added a few touches to ours, as you can see if you download the sample.
Display content based on user role
Now that users are logged in, we display different content depending on their roles. The approach in this sample is to add all functionality and content at design time in Visual Studio, and then remove items with runtime code where appropriate. We could also add new functionality for particular users at runtime, but the sample does not show that option.
In our server-side code, we can get information about the user and modify page content. In the sample, this happens in the Page_PreRenderComplete method. The code to check the user’s role is simple:
private string fullyEnabledRole = "Managers";
if (!User.IsInRole(fullyEnabledRole))
{
// modify page content for role
}
The User object tells us the user name and also whether the user is a member of a particular role. In this case, we check whether the user is in the Managers role. If not, we insert code to modify the page content. In the sample, we have three methods (Subs) that are called within the if statement shown above:
- HideLayer() – hides a specific map layer in the Map and Toc (table of contents) controls
- RemoveItemFromToolbar() – removes a specific item from a toolbar
- RemoveTask() – removes a task from the TaskManager and associated Menu
Finally, we added one other example of setting content based on role. Rather than using code, we used the ASP.NET LoginView control. This control allows you to easily show or hide content based on whether the user is logged in, or if the user is in a particular role. To set up the LoginView control in Visual Studio, you select the view where you want to show some content, and drag the content into the LoginView control. In our case, we created a “RoleGroup” for Managers using the “smart tag” on the LoginView control. Then we dragged a QueryAttributes task into the control. This way, ASP.NET automatically displays the task when someone in Managers is logged in, and hides it from everyone else. The only down side of the LoginView control is that you cannot use it with the TaskManager/Menu option as in the standard Web Mapping Application template. For that case you must use the approach as we did in the RemoveTask() method discussed above.
We hope this sample shows that it is possible, and for some items relatively easy, to add security to your web application. You can secure the entire website, so that all users must log in for any access. You can also secure specific aspects of your application, such as map layers or tasks, based on the user’s role.
Adding context menus to a Web ADF application
The ContextMenu control allows users to interact with your Web ADF application at runtime, usually by right-clicking a component. A ContextMenu can contain one or more context menu items. Each item is associated with an action to execute client or server-side code. In addition, each context menu item may be displayed with an icon andor text. Both the Toc and TaskResults controls include preconfigured ContextMenus to interact with their node content.
The ContextMenu control is not included with the out-of-the-box Web ADF controls integrated with Visual Studio. So, to use the control you can either add a declarative reference in your page or add the ContextMenu control to the Visual Studio toolbox then drag-and-drop it on the page (see Step 1 in Using the ContextMenu control section below). In addition, you must configure context menu items programmatically; no design-time configuration is provided.
- Add the ContextMenu control to the Visual Studio toolbox
Since the ContextMenu control is not added to the Visual Studio toolbox during the Web ADF installation, you need to manually add it. If you have already added the ContextMenu control, skip to the next step.
- In Visual Studio, expand the ArcGIS Web Controls tab in the toolbox. Right-click on the tab and select “Choose Items…”.
- Navigate to the ContextMenu control in the namespace ESRI.ArcGIS.ADF.UI.WebControls and check the box next to the listing. Click OK. The ContextMenu control should now be available in the toolbox.

- Add supporting controls to the page Add a MapResourceManager and Map to the page, then add a valid resource item to the MapResourceManager. In this example, we’ll construct a ContextMenu for use on a Map control. Keep in mind that a ContextMenu can be associated with any element in the page, thus the patterns presented here will apply in other situations.
- Add the ContextMenu control to the page
Drag a ContextMenu control on the page. Note that the location of the ContextMenu control at design-time does not determine the location of the context menu at runtime. Your page should resemble the following:
- Set properties for the ContextMenu control
In design mode, click on the ContextMenu control to select it. Now examine the control’s properties in the Properties window. You don’t have to manually change any of the properties, but it’s recommended that you set the BackColor property to a solid color, for example, white or gray. By default the BackColor property is not set, so the context menu appears transparent at runtime.
- Add context menu items
Adding items and configuring the behavior of a ContextMenu requires writing some code. You can create new context menu items by using the ContextMenuItem class and then adding them to the ContextMenu control. Properties of a ContextMenuItem include the url to an image, the menu item text, and a string representing some custom JavaScript code to execute when the item is clicked. An appropriate time to add new context menu items during the page lifecycle is during the initial page load event. Add the following code to the code behind for your page:
[C#]
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem contextMenuItem = new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem(); contextMenuItem.Text = "Zoom In"; ContextMenu1.Items.Add(contextMenuItem); } } - Add event to show context menu at runtime
In order to display the context menu at the appropriate time, you need to add a browser event to the appropriate control, element, or item in the page. In this case, we want the ContextMenu to be displayed during a right-click on a map. At runtime, the Map control generates a div for display of map data in a browser. A set of attributes events can be configured on the div. One attribute is “oncontextmenu” which enables the browser to listen for right-click events on an element. When this event is triggered, JavaScript code displays the the ContextMenu control and its items. The Web ADF provides a set of JavaScript functions to show and hide context menus. In this case, when the oncontextmenu event is triggered on the map the esriShowContextMenu() JavaScript function will be called and our ContextMenu will be displayed. As in the previous step, an appropriate time to add new attribute information to controls and elements is during the initial page load event. Add the following code (blue) to the existing code added in the previous step (gray):
[C#]
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem contextMenuItem = new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem(); contextMenuItem.Text = "Zoom In"; ContextMenu1.Items.Add(contextMenuItem); string showContextMenu = string.Format("esriShowContextMenu(event,'{0}','{1}','{2}');return false;", ContextMenu1.ClientID, Map1.UniqueID, ""); Map1.Attributes.Add("oncontextmenu", showContextMenu); } }
- Handle click event on context menu item
Once the ContextMenu is displayed at runtime, a user can click on a context menu item to initiate an action. To work with the click event on the server, handle the ItemClicked event on the ContextMenu. When the menu item is clicked, a callback request is sent to the page which contains the context menu. The context menu item can be identified by its text and made available via the ContextMenuItemEventArgs passed to the ItemClicked event. The ContextMenu control is explicitly designed to work with the ASP.NET callback architecture. Implementation code on the server can now interact with server-side content based on the context menu item clicked. Note, the ContextMenu control generates the callback response designed to be processed by the Web ADF JavaScript. As a result, changes to other controls in the page must be packaged as CallbackResults and added to the ContextMenu.CallbackResults property (a collection of CallbackResult objects). More information on Web ADF implementation of the ASP.NET callback framework is available in the topic Working with AJAX capabilities of the Web ADF.
- To handle the ItemClicked event on the ContextMenu in the page, open the ContextMenu property page and view the events (click the lightning bolt button).

- Double-click on the ItemClicked event in the dialog. The code-behind page will display with the implementation method created for you.
- Add the following code to the event handler method. In this case, the Map.Zoom() convenience method will cause the map to zoom in, thus changing the map extent. Since the Map has changed, but the ContextMenu is generating the callback response, the callback results from the Map control need to be copied to the ContextMenu’s callback results collection.
[C#]
protected void ContextMenu1_ItemClicked(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItemEventArgs contextMenuItemEventArgs) { switch (contextMenuItemEventArgs.Item.Text) { case "Zoom In": { Map1.Zoom(2); ContextMenu1.CallbackResults.CopyFrom(Map1.CallbackResults); break; } } }
- To handle the ItemClicked event on the ContextMenu in the page, open the ContextMenu property page and view the events (click the lightning bolt button).
- Using the ContextMenu at runtime
When the Web application starts, the ContextMenu is not visible. Right-click on the control which will show the ContextMenu (In this example it’s the Map control). The ContextMenu will be displayed along with it’s context menu items. In this case, click on the item “Zoom In” to zoom in on the map.
Configuring ArcGIS Server when your IIS Web Site uses a port other than 80
In IIS, if you have your Web Site configured to use a port other than 80, you’ll need to make the following adjustments to ensure that your ArcGIS Server web applications and services work as expected.
These instructions apply if you have ArcGIS Server for the Microsoft .Net Framework 9.2 Service Pack 3 or above.
- If you’re not using the Default Web Site in IIS, first work through the steps in ESRI Knowledge Base Article 32546 before performing the rest of the steps.
- Navigate to your instance folder (if you accepted the default instance name of ArcGIS during install, it’s probably C:InetpubwwwrootArcGIS).
- Expand the Manager folder, then open the Web.config file in a text editor.
- Find the following text: <add key=”PublishPort” value=”80″ />
- Change the value to the port number that you are using and save the changes.
When accessing your published applications, you’ll need to include the port in the URL (for example: http://myServer:8080/myWebMappingApp/Default.aspx). This also applies to ArcGIS Server Manager and the ArcGIS Server Help shortcuts in the Start menu. Right-clicking the shortcut and clicking Properties displays a dialog that you can use to edit the URL referenced by the shortcut.

Working with the Web ADF timeout
Rex Hansen provided this tip on working with the Web ADF timeout
One of the timeouts that you need to be aware of when building Web applications is the Web ADF timeout. The Web ADF timeout provides a single client-side solution for handling an ASP.NET session timeout before a callback or postback can generate an error on the server.
The Web ADF timeout helps provide the user with an understandable error message if the ASP.NET session times out and the application cannot return any more information. When the Web ADF timeout is reached in a Web ADF application, the following error message will tell you that you need to restart the session.

It’s a good practice to keep the Web ADF timeout the same length of time as the ASP.NET session timeout. To control the Web ADF timeout, use the JavaScript variable maximumLapseTime, which is included in the display_common.js file. The timeout value is in minutes. For example, to set the Web ADF timeout to 20 minutes, you would add the following to the form that contains your Web ADF controls:
<script language=”javascript” type=”text/javascript”>
var maximumLapseTime = 20;
</script>
Note: The above code is for the 9.2 Web ADF. At 9.3 you must use the fully qualified name, for example ESRI.ADF.System.maximumLapseTime = 20.
If you have added a programmatic means of keeping the ASP.NET session alive, you can avoid reaching the Web ADF timeout by setting maximumLapseTime = Infinity. Be aware that if the ASP.NET session does time out, clients may not receive the user-friendly error message they would see if the Web ADF timeout were in effect.
You can learn about the maximumLapseTime variable used above, and the other types of timeouts in Timeout settings in the Web ADF and ASP.NET.
Zooming to task results automatically
In this post, Tom Brenneman and Rex Hansen share a control they created that allows you to automatically zoom to the results of a .Net Web ADF task.
This control, called ZoomToResults, enables you to automatically zoom to the result set returned from a task instead of requiring you to navigate through tree-view results in a standard TaskResults control. By default, this control is not visible at runtime. It is designed to simply zoom to the result set in the map if the number of features returned is less than the MaxResultsForMapZoom property. You will need to add this control to a task’s TaskResultsContainers collection to take advantage of these features. Note that this control must be listed before any other container in the collection (e.g. an out-of-the-box TaskResults control). This control was built with version 9.2, Service Pack 3 of the .Net Web ADF.
Follow these steps to use the control in your application.
- In Visual Studio, right click in the Toolbox and click Choose Items.
- Click Browse and navigate to ZoomToResults.dll and click OK.
- Drag the ZoomToResults control onto your web page.
- Set the following properties for ZoomToResults control:
MaxResultsForAutoSelect – this is the maximum result set that will be selected. The results will only be selected if a result set contains this value or less. Set this property to 0 to disable the auto selection capability.
MaxResultsForMapZoom – this is the maximum result set that will be zoomed to. The map will only be zoomed to the result set if it is less than or equal to this value. Set this property to 0 to disable the auto zoom capability.
MinWidthOfZoom – this is the minimum width (or height actually) in map units of the extent rectangle that will be zoomed to. This is particularly useful if the result set is a single point or a very small feature. In this case you could set the minimum extent that the map will zoom to. If you are working with geographic data you may want to make this significantly smaller than the default of 10.
ZoomExtentExpansionPercent – this is the expansion percentage around the extent of the result set for the map to zoom to. This is useful for defining a margin around the extent of features returned in a result set.
DisplayTaskResult – display task results like an out-of-the-box TaskResults control. By default, this property is false.
ShowTaskActivityIndicator – display activity indicator when a task is processing, like an out-of-the-box TaskResults control. By default, this property is false.
- To associate this container with a task, at design-time in design view click on the smart tag on the task and select Choose Task Results container.
- Click Add. Set the Name property of the new BuddyControl to the name of the ZoomToResult control (e.g. ZoomtoResults1).
- In the BuddyControl Collection Editor click the up arrow to move the ZoomToResults buddy control to the top of the list.
- Click OK to dismiss the BuddyControl Collection Editor.
- Try out the app!
Download the 9.2 control (The compressed folder contains the code with extensive comments from Tom and Rex, as well as a Readme file with the above instructions.)
Updated download for ArcGIS Server 9.3
Transparency in graphics layers with callbacks
In this post, Bryan Baker provides a tip for .Net developers working with the Web ADF graphics layer:
Several developers have asked questions about handling transparency in graphics layers when they are working with ASP.NET callbacks (a callback is a way to get information from the server without completely refreshing the page–more discussion available on callbacks is in the developer kit for ArcGIS Server). The graphics layer should be transparent to show the map service underneath in the browser. Instead, sometimes the map display becomes opaque with a light blue background, like this:

Usually this is seen with Internet Explorer 6. Internet Explorer 7 and Firefox often display the same page with the graphics layer as transparent. Typically, tiles generated subsequently, such as by panning or zooming the map, will display properly.
The cause of this problem is that extra callback results are being sent to the browser, causing the opaque graphics layer to be generated for tiles in the current view. More details on the cause in a minute, but let’s show how to fix the problem:
Eliminate unnecessary copying of callback results
To make the graphics transparent, find and eliminate unneeded statements that copy callback results. In your code, you probably have one or more statements that copy callback results to the control that initiated the callback. For instance, if you create a custom task that triggers a callback, you might have a statement that copies the results of refreshing the Map to the task. An example might be:
[VB]
Me.CallbackResults.CopyFrom(mapControl.CallbackResults)
[C#]
this.CallbackResults.CopyFrom(mapCtrl.CallbackResults);
Other variations include CallbackResults.CopyTo, or using CallbackResults.Add to add the results from another control. If you are experiencing the transparency problem, try commenting out this line in your code that handles the callback.
Another way this same behavior can be triggered is to generate multiple sets of callback results within a control. For example, a custom task or tool might already have internal logic to refresh the Map. If you then explicitly add your own Map.Refresh statement, extra callback results can be generated, triggering the problem. In this case, look for a statement such as:
[VB]
mapControl.Refresh()
[C#]
mapControl.Refresh();
We have found that eliminating one or more of these kinds of statements will usually resolve the problem with transparency of the graphics layer.
Some details
If you are interested in why this behavior occurs, here are some details. Some of the ESRI Web ADF controls will copy the callback results from the Map for you. This will occur if the ADF control responsible for generating the callback results can find the Map. For example, your custom task may be buddied with a TaskResults control, which typically is buddied to a Map. In this case, the Map’s callback results will be added to the callback results of the TaskResults. The TaskResults callback results are then added to the custom task’s callback results for you. A similar situation may be encountered when working with a custom command in a Toolbar. If the Toolbar is buddied with a Map, the Map’s callback results will be added to the Toolbar’s callback results.
If you add a dynamic graphics resource to your application, and then copy a duplicate set of callback results to the control responsible for generating the callback response (for example, a custom task), the background of the graphics resource in Internet Explorer 6 will not initially be transparent. Internet Explorer 7 and Firefox can handle the duplicate callbacks, so the background appears transparent in those browsers.
Welcome to Mobile Central!
Mobile Central is a new site that is written and managed directly by members of the Mobile development team located in Redlands, California. We are really excited to have this opportunity to share with you the most current and relevant information about building mobile applications using the ArcGIS Mobile SDK. Topics we will discuss on the site will range from very detailed discussion of programming best practices to strategies for deploying mobile applications and data to your field workers.
Mobile GIS is an emerging technology and now is the right time to start planning how to bring your GIS to the field using ArcGIS Mobile. Our goal is to make Mobile Central your primary source for information when developing and deploying your mobililty solution.
Stay tuned for more…
