Hi All,Looking through the samples and API docs, the only direct access to a feature's attachments is via FeatureLayer::QueryAttachmentInfos(). Is there, or will there be in v2.2 of the API, a similar method for a MapServer layer? The only way I can see to do it now is through the service's REST end point. The code below is an adaptation of the ESRI Identify sample which uses the REST serive to check for attachments and builds a series of hyperlink buttons to open them if so. I can't really use the AttachmentEditor control for this since it a) requires a FeatureLayer and most of my services do not have this enabled, b) the Identify task returns results from multiple layers, and c) I don't want folks to be able to add or delete attachments.Anyone know of another way to do this? Thanks, Terry
private void IdentifyTask_ExecuteCompleted(Object sender, IdentifyEventArgs args)
{
if (this.Visibility == Visibility.Collapsed)
{
this.Visibility = Visibility.Visible;
}
IdentifyResultsPanel.Visibility = Visibility.Visible;
AddResultstoControl(args.IdentifyResults, args.UserState);
}
private void AddResultstoControl(List<IdentifyResult> results, object token)
{
//token contains the map layer index
if (_dataItems == null)
{
_dataItems = new List<DataItem>();
}
if (_dataLinks == null)
{
_dataLinks = new Dictionary<string, List<DataLink>>();
}
if ((results != null) && (results.Count > 0))
{
Graphic feature = null;
string title = string.Empty;
string oid = string.Empty;
WebClient web = null;
WebClient webAttach = null;
string urlLayer = string.Empty;
string urlFeature = string.Empty;
bool hasOID = false;
foreach (IdentifyResult result in results)
{
web = new WebClient();
webAttach = new WebClient();
urlFeature = string.Empty;
hasOID = false;
feature = result.Feature;
title = result.Value.ToString() + " (" + result.LayerName + ")";
urlLayer = MapUtils.GetLayerURL(_Map.Layers[Convert.ToInt32(token.ToString())]) + "/" + result.LayerId;
foreach (KeyValuePair<string,object> kvp in result.Feature.Attributes)
{
switch (kvp.Key.ToLower())
{
case "objectid":
case "fid":
urlFeature = urlLayer + "/" + kvp.Value.ToString();
_dataItems.Add(new DataItem() { Title = title, Data = feature.Attributes, Id = urlFeature });
_dataLinks.Add(urlFeature, new List<DataLink>() );
cbxIdentify.Items.Add(title);
urlFeature += "/attachments?f=json";
hasOID = true;
break;
default:
break;
}
if (hasOID)
{
break;
}
}
//see if layer hasAttachements; download them if so
web.DownloadStringCompleted += (s, e) =>
{
bool hasAttachments = false;
JsonObject jsObj = (JsonObject)JsonObject.Parse(e.Result);
if (jsObj.ContainsKey("hasAttachments"))
{
hasAttachments = Convert.ToBoolean(jsObj["hasAttachments"].ToString());
}
else
{
hasAttachments = false;
}
if (hasAttachments)
{
webAttach = new WebClient();
webAttach.DownloadStringCompleted += web_DownloadStringCompleted;
webAttach.DownloadStringAsync(new Uri(urlFeature), urlFeature);
}
};
web.DownloadStringAsync(new Uri(urlLayer + "?f=json"));
}
cbxIdentify.UpdateLayout();
//cbxIdentify.SelectedIndex = 0;
}
}
void web_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//e will have the JSON of a features attachments
string urlbase = e.UserState.ToString().Replace("/attachments?f=json", "");
DataLink dl = null;
JsonObject jsObj = (JsonObject)JsonObject.Parse(e.Result);
if (jsObj.ContainsKey("error"))
{
return;
}
JsonArray AttachInfos = (JsonArray)jsObj["attachmentInfos"];
foreach (JsonObject jOb in AttachInfos)
{
dl = new DataLink() { Caption = jOb["name"].ToString().Trim('"'), Link = new Uri(urlbase + "/attachments/" + jOb["id"].ToString()) };
_dataLinks[urlbase].Add(dl);
}
}
//class for data grid binding
private class DataItem
{
private string _id;
private string _Title;
private IDictionary<string, Object> _Data;
public string Id
{
get { return _id; }
set {_id = value;}
}
public string Title
{
get { return _Title; }
set { _Title = value; }
}
public IDictionary<string, Object> Data
{
get { return _Data; }
set { _Data = value; }
}
}
//for storing links to attachments
private class DataLink
{
private Uri _link;
private string _caption;
public Uri Link
{
get { return _link; }
set { _link = value; }
}
public string Caption
{
get { return _caption; }
set { _caption = value;}
}
}