C# WCF中的动态扩展对象
尝试使用枚举类型进程和动态数据的操作对我的服务进行Ping/PongC# WCF中的动态扩展对象,c#,wcf,dynamic,C#,Wcf,Dynamic,尝试使用枚举类型进程和动态数据的操作对我的服务进行Ping/Pong [ServiceContract ( CallbackContract = typeof ( iStackoverflowCallBack ) )] public interface iStackoverflow { [OperationContract] void Ping ( Process Operation , dynamic Data ); } [ServiceContract ( )] publi
[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 );
}
为什么此服务存在连接问题
- 实现两个接口时,
自动转换为动态
对象
- 当
ing消费者提供我的服务时,ping根本无法到达服务,但服务工作正常ping
解决方案:
[DataContract]
public class SerializableDynamicObject : IDynamicMetaObjectProvider
{
[DataMember]
private IDictionary<string,object> dynamicProperties = new Dictionary<string,object>();
#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<string> 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<string> GetDynamicMemberNames ()
{
var dynObj = (SerializableDynamicObject)this.Value;
return dynObj.getDynamicMemberNames();
}
}
[DataContract]
公共类SerializableDynamicObject:IDynamicMetaObjectProvider
{
[数据成员]
私有IDictionary dynamicProperties=新字典();
#区域IDynamicMetaObjectProvider实现
公共DynamicMetaObject GetMetaObject(表达式)
{
返回新的SerializableDynamicMetaObject(表达式,
BindingRestrictions.GetInstanceRestriction(表达式,this),this);
}
#端区
#支持动态元对象的区域辅助方法
内部对象设置值(字符串名称、对象值)
{
dynamicProperties.Add(名称、值);
返回值;
}
内部对象getValue(字符串名称)
{
目标价值;
如果(!dynamicProperties.TryGetValue(名称,输出值)){
值=空;
}
返回值;
}
内部IEnumerable getDynamicMemberNames()
{
返回dynamicProperties.key;
}
#端区
}
公共类SerializableDynamicMetaObject:DynamicMetaObject
{
类型objType;
public SerializableDynamicMetaObject(表达式、绑定限制、对象值)
:base(表达式、限制、值)
{
objType=value.GetType();
}
公共重写DynamicMetaObject BindGetMember(GetMemberBinder binder)
{
var self=this.Expression;
var dynObj=(SerializableDynamicObject)this.Value;
var keyExpr=表达式.Constant(binder.Name);
var getMethod=objType.getMethod(“getValue”,BindingFlags.NonPublic | BindingFlags.Instance);
var target=Expression.Call(Expression.Convert(self,objType)),
getMethod,
keyExpr);
返回新的DynamicMetaObject(目标,
BindingRestrictions.getTypeRestrictions(self,objType));
}
公共重写DynamicMetaObject BindSetMember(SetMemberBinder binder,DynamicMetaObject值)
{
var self=this.Expression;
var keyExpr=表达式.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);
返回新的DynamicMetaObject(目标,
BindingRestrictions.getTypeRestrictions(self,objType));
}
公共重写IEnumerable GetDynamicMemberNames()
{
var dynObj=(SerializableDynamicObject)this.Value;
返回dynObj.getDynamicMemberNames();
}
}
任何WCF操作协定的参数必须是WCF数据协定(或基元类型),否则数据将不会序列化和传输
详细介绍Ahmed关于如何使用它的解决方案 答案取自本页: 但是请记住,WCF需要数据类型的知识,因为它是最基本的数据类型,如
string
,int
等,这不是问题。但是,如果在动态对象中使用自定义数据类型,则必须使用[KnownType(typeof(XXX))]
指令在中定义。
这适用于枚举
、列表
和任何其他自定义类
例如:
[KnownType(typeof(MyCustomEnum))]
[KnownType(typeof(List<object>))]
[DataContract]
public class SerializableDynamicObject : IDynamicMetaObjectProvider
...
[KnownType(typeof(MyCustomEnum))]
[知识类型(类型(列表))]
[数据合同]
公共类SerializableDynamicObject:IDynamicMetaObjectProvider
...
那么如何发送未知的已知数据包?数据来自哪里?你能把它序列化成一个字符串吗?我很快就找到了这个。查看它是否适用于您:有关代码的解释,请参阅。
dynamic d = new SerializableDynamicObject();
d.Name = “SomeData”;
d.Address = new SerializableDynamicObject();
d.Address.Line1 = “123 Spring St.”;
dynamic a = new SerializableDynamicObject();
a.Items = new List(new object[] { d, d });
return a;
[KnownType(typeof(MyCustomEnum))]
[KnownType(typeof(List<object>))]
[DataContract]
public class SerializableDynamicObject : IDynamicMetaObjectProvider
...