1、 WCF中的綁定。
可以通過綁定無參數構造函數實例化綁定,然后調用CreateBindingElements獲取到此種綁定的綁定元素。
BindingElementCollection collection = httpBinding.CreateBindingElements();
foreach (var element in collection)
{
Console.WriteLine(element.GetType().FullName);
}
輸入如下:

如果對WSHttpBinding 更換一下構造函數 ,如:
httpBinding = new WSHttpBinding(SecurityMode.Transport);
輸出結果如下:
2、終結點契約配置
3、 UnHandler處理器
的參數可以指定為Message。這種服務操作在WCF中被稱為UnHandler處理器。這種情況下,參數應為Message;
返回值為void或者Message;OperationCOntractAtrribte的Action設置為"*"
4、WCF序列化中Dos攻擊
防止Dos攻擊,在DataContractSerializer中使用MaxItemsInObjectGraph設置了每次序列化得對
象數量。實際使用的時候可以在實現服務契約接口的服務加上ServiceBehavior標簽中進行設置。如:[ServiceBehavior(MaxItemsInObjectGraph = 60)];或者在serviceBehavior的配置中由
dataContractSerializer指定。如:
<dataContractSerializer maxItemsInObjectGraph="1000"/>
</behavior>
5、泛型數據契約問題。
泛型為OO里的一種概念,而服務是基於SOA的,它沒有重載等概念。WCF的默認序列化器DataContractSerializer對
泛型數據契約的序列化,生成的XML默認的根節點元素名稱為:類型名+泛型名1+泛型名2+...+哈希碼。
可以通過指定模板的形式指定DataContractSerializer序列化后的根節點名:{0}{1}...{n}{#}。當然如果能保證數據契約名稱不重復,也可以直接在DataContract中通過Name指定。
自定義集合數據契約:定義類,實現集合接口。如下定義:
{
private readonly IList<Teacher> teachers = new List<Teacher>();
public TeacherCollection()
{
}
public TeacherCollection(IList<Teacher> _teachers)
{
teachers = _teachers;
}
public void Add(Teacher teacher)
{
teachers.Add(teacher);
}
#region IEnumerable<Teacher> 成員
public IEnumerator<Teacher> GetEnumerator()
{
return teachers.GetEnumerator();
}
#endregion
#region IEnumerable 成員
IEnumerator IEnumerable.GetEnumerator()
{
return teachers.GetEnumerator();
}
#endregion
}
在定義契約接口時,可以用自定義集合數據契約。它和IList<Teacher>的區別是:IList<Teacher>中Teacher才是數據契約,IList<Teacher>是數據契約的集合,而TeacherCollection是將整個集合對象最為數據契約。在WCF的默認的序列化器對TeacherCollection和IList<Teacher>的序列化的結果是相同的。
public class Collection<T> : List<T>
{
private readonly IList<Teacher> teachers = new List<Teacher>();
}
7、數據契約代理。
DataContractSerializer中,用於將數據契約類與其他相似類型的轉化。以下實現Contract類型與
數據契約Employee之間的轉化。
{
public string FullName { get; set; }
public string Sex { get; set; }
}
public class Employee
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string Gender { get; set; }
}
{
#region IDataContractSurrogate 成員
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
return null;
}
public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType)
{
return null;
}
public Type GetDataContractType(Type type)
{
if (type== typeof(Contract))
{
return typeof (Employee);
}
return type;
}
public object GetDeserializedObject( object obj, Type targetType)
{
Employee employee = obj as Employee;
if (employee== null)
{
return obj;
}
return new Contract {FullName = employee.FirstName + employee.LastName, Sex = employee.Gender};
}
public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes)
{
}
public object GetObjectToSerialize( object obj, Type targetType)
{
Contract contract = obj as Contract;
if (contract == null)
{
return obj;
}
return new Employee
{
FirstName = contract.FullName.Split( " ".ToArray(), StringSplitOptions.None)[ 0],
Gender = contract.Sex,
LastName = contract.FullName.Split( " ".ToArray(), StringSplitOptions.None)[ 1]
};
}
public Type GetReferencedTypeOnImport( string typeName, string typeNamespace, object customData)
{
return null;
}
public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit)
{
return typeDeclaration;
}
#endregion
}
使用ContactSurrogate進行序列化與反序列化的方法:
{
DataContractSerializer serializer= new DataContractSerializer( typeof(T), null,Int32.MaxValue, false, false,dataContractSurrogate);
using(XmlWriter xmlWriter=XmlWriter.Create(fileName))
{
serializer.WriteObject(xmlWriter, instance);
}
Process.Start(fileName);
}
public static T DeSerializer<T>( string fileName,IDataContractSurrogate dataContractSurrogate)
{
DataContractSerializer serializer = new DataContractSerializer( typeof(T), new List<Type>(), Int32.MaxValue, false, false, dataContractSurrogate);
using (XmlReader xmlReader=XmlReader.Create(fileName))
{
object obj = serializer.ReadObject(xmlReader);
return (T) obj;
}
}
現在對數據契約Employee使用Serializer<T>進行序列化,然后將它序列化后的文件使用
DeSerializer<T>將它反序列化成反序列化為Contract對象。
ContactSurrogate contactSurrogate = new ContactSurrogate();
Tools.Serializer(employee, @"C:\DataContractSurrogate.txt", contactSurrogate);
Contract obj = Tools.DeSerializer<Contract>(@"C:\DataContractSurrogate.txt", contactSurrogate);
Console.WriteLine(string.Format("{0} 類型為:{1}。FullName is {2},Sex is {3}",obj,obj.GetType().FullName,obj.FullName,obj.Sex));