Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF中的动态扩展对象_C#_Wcf_Dynamic - Fatal编程技术网

C# WCF中的动态扩展对象

C# 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

尝试使用枚举类型进程和动态数据的操作对我的服务进行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 );
}
为什么此服务存在连接问题

  • 实现两个接口时,
    动态
    自动转换为
    对象
  • ping
    ing消费者提供我的服务时,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
...