WCF中的动态ExpandoObject

尝试使用枚举类型过程和动态数据操作Ping / Pong我的服务。

[ServiceContract ( CallbackContract = typeof ( iStackoverflowCallBack ) )] public interface iStackoverflow { [OperationContract] void Ping ( Process Operation , dynamic Data ); } [ServiceContract ( )] public interface iStackoverflowCallBack { [OperationContract] void Pong ( Process Operation , dynamic Data ); } 

为什么这项服务有连接问题?

  • 当实现两个接口时, dynamic自动转换为object
  • 当从消费者ping我的服务时,ping根本不会到达服务,但服务正常工作。

方案:

 [DataContract] public class SerializableDynamicObject : IDynamicMetaObjectProvider { [DataMember] private IDictionary dynamicProperties = new Dictionary(); #region IDynamicMetaObjectProvider implementation public DynamicMetaObject GetMetaObject (Expression expression) { return new SerializableDynamicMetaObject(expression, BindingRestrictions.GetInstanceRestriction(expression, this), this); } #endregion #region Helper methods for dynamic meta object support internal object setValue(string name, object value) { dynamicProperties.Add(name, value); return value; } internal object getValue(string name) { object value; if(!dynamicProperties.TryGetValue(name, out value)) { value = null; } return value; } internal IEnumerable getDynamicMemberNames() { return dynamicProperties.Keys; } #endregion } public class SerializableDynamicMetaObject : DynamicMetaObject { Type objType; public SerializableDynamicMetaObject(Expression expression, BindingRestrictions restrictions, object value) : base(expression, restrictions, value) { objType = value.GetType(); } public override DynamicMetaObject BindGetMember (GetMemberBinder binder) { var self = this.Expression; var dynObj = (SerializableDynamicObject)this.Value; var keyExpr = Expression.Constant(binder.Name); var getMethod = objType.GetMethod("getValue", BindingFlags.NonPublic | BindingFlags.Instance); var target = Expression.Call(Expression.Convert(self, objType), getMethod, keyExpr); return new DynamicMetaObject(target, BindingRestrictions.GetTypeRestriction(self, objType)); } public override DynamicMetaObject BindSetMember (SetMemberBinder binder, DynamicMetaObject value) { var self = this.Expression; var keyExpr = Expression.Constant(binder.Name); var valueExpr = Expression.Convert(value.Expression, typeof(object)); var setMethod = objType.GetMethod("setValue", BindingFlags.NonPublic | BindingFlags.Instance); var target = Expression.Call(Expression.Convert(self, objType), setMethod, keyExpr, valueExpr); return new DynamicMetaObject(target, BindingRestrictions.GetTypeRestriction(self, objType)); } public override IEnumerable GetDynamicMemberNames () { var dynObj = (SerializableDynamicObject)this.Value; return dynObj.getDynamicMemberNames(); } } 

任何WCF操作合同的参数必须是WCF数据协定(或原始类型),否则数据将不会被序列化和传输。

http://msdn.microsoft.com/en-us/library/ms733127.aspx