WCF Tips之一
集合元素類的定義如下:
public enum FileType
{
TXT,DOC,HTML,OTHER
}
[DataContract]
public class Document
{
private string m_localPath;
private string m_fileName;
private FileType m_fileType;
[DataMember]
public string LocalPath
{
get { return m_localPath; }
set { m_localPath = value; }
}
[DataMember]
public string FileName
{
get { return m_fileName; }
set { m_fileName = value; }
}
[DataMember]
public FileType FileType
{
get { return m_fileType; }
set { m_fileType = value; }
}
}
自定義集合DocumentList則實現 了IList<Document>接口:
//which attribute should be applied here?
public class DocumentList:IList<Document>
{
private IList<Document> m_list = null;
public DocumentList()
{
m_list = new List<Document>();
}
#region IList<Document> Members
public int IndexOf (Document item)
{
return m_list.IndexOf (item);
}
public void Insert(int index, Document item)
{
m_list.Insert (index,item);
}
public void RemoveAt (int index)
{
m_list.RemoveAt(index);
}
public Document this[int index]
{
get
{
return m_list[index];
}
set
{
m_list[index] = value;
}
}
#endregion
#region ICollection<Document> Members
public void Add(Document item)
{
m_list.Add (item);
}
public void Clear()
{
m_list.Clear();
}
public bool Contains(Document item)
{
return m_list.Contains(item);
}
public void CopyTo(Document[] array, int arrayIndex)
{
m_list.CopyTo(array,arrayIndex);
}
public int Count
{
get { return m_list.Count; }
}
public bool IsReadOnly
{
get { return m_list.IsReadOnly; }
}
public bool Remove(Document item)
{
return m_list.Remove(item);
}
#endregion
#region IEnumerable<Document> Members
public IEnumerator<Document> GetEnumerator()
{
return m_list.GetEnumerator();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) m_list).GetEnumerator();
}
#endregion
}
注意,對於自定義集合DocumentList而 言,我們不能應用[DataContract]特性,否則會在服務操作中無法返回正確的 DocumentList對象。例如如下的服務操作定義,實際上無法獲得正確的 DocumentList值:
[OperationContract]
[FaultContract (typeof(DirectoryNotFoundException))]
DocumentList FetchDocuments(string homeDir);
我們應該為DocumentList施 加[CollectionDataContract]或者[Serializable],建議采用前者。因為對於自 定義集合而言,如果是泛型集合,還可以利用Name屬性制定導出元數據生成的類 型名。不過,對於本例的集合而言,由於沒有泛型參數,則無所謂了。為了在導 出元數據時識別集合的元素Document類型,當然,還需要施加 KnowTypeAttribute,最後的定義修改如下:
[KnownType(typeof (Document))]
[CollectionDataContract]
[Serializable]
public class DocumentList:IList<Document>
{}
此時,客戶端應用程序可以直接使用數據契約,仍然能夠識別。