This document is archived and information here might be outdated.  Recommended version.


Working with feature attachments (ArcObjects .NET 10.5 SDK)

Working with feature attachments


Summary
This topic discusses how to create attachment tables and how to access, create, and modify feature attachments.

In this topic


Attachment tables

To create feature attachments, an attachment table must exist for a feature class. To access, create, or remove a feature class's attachment table, cast the class to the ITableAttachments interface. This interface exposes the following properties:
  • HasAttachments—Read-only Boolean property that indicates whether an attachment table exists for a feature class.
  • AttachmentManager—Read-only property instantiates and returns an attachment manager for the feature class and its attachment table. An attachment manager is used to query, add, delete, and update attachments through the IAttachmentManager interface.
ITableAttachments also defines the following methods (both have void return types and no parameters):
  • AddAttachments—Creates an attachment table for the feature class. Feature classes cannot have multiple attachment tables.
  • DeleteAttachments—Deletes the attachment table.
When an attachment table is created, a composite one-to-many relationship class is also created between the feature class and its attachment table. Since the relationship class is composite, developers should be aware that deleting features also deletes any attachments the features might have.

Querying attachments

There are two ways to browse attachments: by the ObjectIDs of the attachments and by the ObjectIDs of the features they are attached to. The methods used in both cases—GetAttachmentsByAttachmentIDs and GetAttachmentsByParentIDs, respectively—are very similar. Both of these methods take two parameters, an array of ObjectIDs and a Boolean, and return an enumerator of attachments.
The Boolean parameter ("Info Only") of these methods determines which properties of the returned attachments will be populated. The IAttachment interface defines the following properties:
  • AttachmentID—Attachment's ObjectID.
  • ContentType—Describes the type of data contained in the attachment.
  • Data—Attachment's data.
  • Name—Attachment's file name.
  • ParentID—ObjectID of the associated feature.
  • Size—Size of the attachment's data in bytes.
If the "Info Only" parameter is true, the Data property is returned as a null value. This provides applications with an efficient way of browsing attachments. However, if the client code retrieves the attachment's data, the "Info Only" parameter should be false.
The following code example shows how to browse the attachments associated with a feature that has an ObjectID of 1:
[C#]
// Get the class's attachment manager.
ITableAttachments tableAttachments=(ITableAttachments)featureClass;
IAttachmentManager attachmentManager=tableAttachments.AttachmentManager;

// Create an array and add the feature's ObjectID to it.
ILongArray parentIdArray=new LongArrayClass();
parentIdArray.Add(1);

// Retrieve the attachments, writing their Attachment IDs and names to the console.
IEnumAttachment enumAttachment=attachmentManager.GetAttachmentsByParentIDs
    (parentIdArray, true);
enumAttachment.Reset();
IAttachment attachment=null;
while ((attachment=enumAttachment.Next()) != null)
{
    Console.WriteLine("{0}: {1}", attachment.AttachmentID, attachment.Name);
}
[VB.NET]
' Get the class's attachment manager.
Dim tableAttachments As ITableAttachments=CType(featureClass, ITableAttachments)
Dim attachmentManager As IAttachmentManager=tableAttachments.AttachmentManager

' Create an array and add the feature's ObjectID to it.
Dim parentIdArray As ILongArray=New LongArrayClass()
parentIdArray.Add(1)

' Retrieve the attachments, writing their Attachment IDs and names to the console.
Dim enumAttachment As IEnumAttachment=attachmentManager.GetAttachmentsByParentIDs(parentIdArray, True)
enumAttachment.Reset()
Dim attachment As IAttachment=enumAttachment.Next()
While Not attachment Is Nothing
    Console.WriteLine("{0}: {1}", attachment.AttachmentID, attachment.Name)
    attachment=enumAttachment.Next()
End While
The order in which attachments are returned by the attachment manager is not guaranteed.
To work with an attachment's data, use the IMemoryBlobStream interface. The following code example shows how to save an attachment's file to disk given a known Attachment ID:
[C#]
// Create an array and add the attachment's Attachment ID to it.
ILongArray attachmentIdArray=new LongArrayClass();
attachmentIdArray.Add(attachmentID);

// Retrieve the attachment, saving its data to the current directory.
IEnumAttachment enumAttachment=attachmentManager.GetAttachmentsByAttachmentIDs
    (attachmentIdArray, false);
enumAttachment.Reset();
IAttachment attachment=enumAttachment.Next();
if (attachment != null)
{
    IMemoryBlobStream memoryBlobStream=attachment.Data;
    memoryBlobStream.SaveToFile(attachment.Name);
}
[VB.NET]
' Create an array and add the attachment's Attachment ID to it.
Dim attachmentIdArray As ILongArray=New LongArrayClass()
attachmentIdArray.Add(attachmentID)

' Retrieve the attachment, saving its data to the current directory.
Dim enumAttachment As IEnumAttachment=attachmentManager.GetAttachmentsByAttachmentIDs(attachmentIdArray, False)
enumAttachment.Reset()
Dim attachment As IAttachment=enumAttachment.Next()
If Not attachment Is Nothing Then
    Dim memoryBlobStream As IMemoryBlobStream=attachment.Data
    memoryBlobStream.SaveToFile(attachment.Name)
End If

Adding attachments

Adding attachments to a feature is a three-step process, assuming the feature's ObjectID is known. See the following:
  1. Load a file into a memory blob stream.
  2. Instantiate an attachment and set its properties.
  3. Use the attachment manager to apply the attachment to the feature.
The following code example shows how to do this:
[C#]
// Open a file as a memory blob stream.
IMemoryBlobStream memoryBlobStream=new MemoryBlobStreamClass();
memoryBlobStream.LoadFromFile("Image1.png");

// Create an attachment.
IAttachment attachment=new AttachmentClass
{
    ContentType="image/png", Data=memoryBlobStream, Name="Image1.png"
};

// Assign the attachment to the feature with ObjectID (OID)=1.
attachmentManager.AddAttachment(1, attachment);
[VB.NET]
' Open a file as a memory blob stream.
Dim memoryBlobStream As IMemoryBlobStream=New MemoryBlobStreamClass()
memoryBlobStream.LoadFromFile("Image1.png")

' Create an attachment.
Dim attachment As IAttachment=New AttachmentClass With _
                                { _
                                .ContentType="image/png", _
                                .Data=memoryBlobStream, _
                                .Name="Image1.png" _
                                }

' Assign the attachment to the feature with ObjectID (OID)=1.
attachmentManager.AddAttachment(1, attachment)

Deleting attachments

IAttachmentManager has the following methods that can be used to delete attachments:
As previously mentioned, due to the composite relationship class between feature classes and their attachment tables, attachments are automatically deleted if the features they are associated with are deleted.

Updating attachments

To update an attachment, use GetAttachmentsByParentIDs or GetAttachmentsByAttachmentIDs to retrieve one or more attachments, modify the attachments using the IAttachment interface, then pass each modified attachment to the IAttachmentManager.UpdateAttachment method to persist the changes to the geodatabase.
Not all properties of an attachment can be modified. For example, Attachment IDs and Parent IDs are immutable. The Size property cannot be manually changed, but it is recalculated when the attachment's data is changed.
The following code example shows how to rename an attachment:
[C#]
// Rename a previously retrieved attachment and persist the change.
attachment.Name="LosAngeles.png";
attachmentManager.UpdateAttachment(attachment);
[VB.NET]
' Rename a previously retrieved attachment and persist the change.
attachment.Name="LosAngeles.png"
attachmentManager.UpdateAttachment(attachment)






To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Additional Requirements
  • Although ArcGIS Desktop users can use attachments from existing attachment tables with a Basic license, creating attachment tables in an ArcSDE geodatabase requires a Standard or an Advanced license. Likewise, ArcGIS Engine users can use the majority of functionality described in this topic, but the Geodatabase Update extension is required to create attachment tables in ArcSDE geodatabases.

Development licensing Deployment licensing
ArcGIS Desktop Basic ArcGIS Desktop Basic
ArcGIS Desktop Standard ArcGIS Desktop Standard
ArcGIS Desktop Advanced ArcGIS Desktop Advanced
Engine Developer Kit Engine