locked
Passing dynamically created objects via WCF RRS feed

  • Question

  • Hi,

    I am creating generic objects at run time using Reflection.Emit assembly. This object is referenced inside another object which I am trying to pass back to client from my service.

    This results in an error as the dynamically created object is not known to Service and it is not able to serialize/deserialize it.

    I referred to this link which tells as how to make a service aware of KnownTypes using some settings in config file.

    http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/9f3647ec-ff29-45b4-9277-9036ec0a2bb9/

    My problem is that the assembly in which my object is created is also created at run time. The name of the class is also not unique and gets generated at runtime only. I am not able to figure out how to programmatically make my service aware of this dynamic type at run time.

    Tried working on DataContarctResolver which is provided in .net 4.0 but all the examples showed were refererring to pre-existing classes and didnot find any solution for run time generated objects in runtime generated assemblies.

    I am stuck in this problem for last three days and badly need to figure out the possibility of this scenario.

    Looking forward for the responses.

    Thanks & Regards

    Prachi

    Saturday, September 17, 2011 10:21 AM

Answers

  • As long as you have a reference to the dynamically-generated type (either passed to the resolver, or created by the resolver itself), the resolver should be able to work out fine. The example below shows a reflection.emit type being passed as a member of another object to a service.

        public class Post_79533008_cb7f_478d_9f34_24ed85f5cd51
        {
            [DataContract]
            public class MyHolder
            {
                [DataMember]
                public object Value;
    
                public override string ToString()
                {
                    return string.Format("MyHolder[Value={0}]", this.Value);
                }
            }
            [ServiceContract]
            public interface ITest
            {
                [OperationContract]
                MyHolder EchoHolder(MyHolder holder);
            }
            public class Service : ITest
            {
                public MyHolder EchoHolder(MyHolder holder)
                {
                    return holder;
                }
            }
            private static void SetResolver(ServiceEndpoint endpoint)
            {
                foreach (var operation in endpoint.Contract.Operations)
                {
                    DataContractSerializerOperationBehavior dcsob = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
                    if (dcsob != null)
                    {
                        dcsob.DataContractResolver = new DynamicTypeResolver(ReflectionEmitHelper.CreatePersonType());
                    }
                }
            }
            public static void Test()
            {
                string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
                ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
                ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
                SetResolver(endpoint);
                host.Open();
                Console.WriteLine("Host opened");
    
                ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
                SetResolver(factory.Endpoint);
                ITest proxy = factory.CreateChannel();
    
                Type personType = ReflectionEmitHelper.CreatePersonType();
                object person = Activator.CreateInstance(personType);
                personType.GetProperty("Name").SetValue(person, "John Doe", null);
                personType.GetProperty("Age").SetValue(person, 22, null);
                Console.WriteLine("Person: {0}", person);
    
                MyHolder holder = new MyHolder { Value = person };
                Console.WriteLine("Sending holder over the wire: {0}", holder);
                var newHolder = proxy.EchoHolder(holder);
                Console.WriteLine("Received holder over the wire: {0}", newHolder);
    
                ((IClientChannel)proxy).Close();
                factory.Close();
    
                Console.Write("Press ENTER to close the host");
                Console.ReadLine();
                host.Close();
            }
    
            class DynamicTypeResolver : DataContractResolver
            {
                Type dynamicType;
                public DynamicTypeResolver(Type dynamicType)
                {
                    this.dynamicType = dynamicType;
                }
    
                public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
                {
                    if (typeNamespace == "http://dynamic/" + ReflectionEmitHelper.AssemblyName && typeName == this.dynamicType.Name)
                    {
                        return this.dynamicType;
                    }
                    else
                    {
                        return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null);
                    }
                }
    
                public override bool TryResolveType(Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
                {
                    if (type.Assembly.GetName().Name == ReflectionEmitHelper.AssemblyName)
                    {
                        XmlDictionary dic = new XmlDictionary();
                        typeName = dic.Add(type.Name);
                        typeNamespace = dic.Add("http://dynamic/" + ReflectionEmitHelper.AssemblyName);
                        return true;
                    }
                    else
                    {
                        return knownTypeResolver.TryResolveType(type, declaredType, null, out typeName, out typeNamespace);
                    }
                }
            }
    
            static class ReflectionEmitHelper
            {
                public const string AssemblyName = "MyReflectionEmitAssembly";
                static Type personType;
    
                internal static Type CreatePersonType()
                {
                    if (personType == null)
                    {
                        AppDomain myDomain = AppDomain.CurrentDomain;
                        AssemblyName myAsmName = new AssemblyName(AssemblyName);
                        AssemblyBuilder myAssembly =
                            myDomain.DefineDynamicAssembly(myAsmName,
                                AssemblyBuilderAccess.RunAndSave);
    
                        ModuleBuilder myModule =
                            myAssembly.DefineDynamicModule(myAsmName.Name,
                               myAsmName.Name + ".dll");
    
                        // public class Person
                        TypeBuilder personTypeBuilder =
                            myModule.DefineType("Person", TypeAttributes.Public);
    
                        // Add [DataContract] to the type
                        Type dcaType = typeof(DataContractAttribute);
                        CustomAttributeBuilder dataContractBuilder = new CustomAttributeBuilder(
                            dcaType.GetConstructor(Type.EmptyTypes),
                            new object[0],
                            new PropertyInfo[] { dcaType.GetProperty("Name"), dcaType.GetProperty("Namespace") },
                            new object[] { "Person", "http://my.dynamic.namespace" });
                        personTypeBuilder.SetCustomAttribute(dataContractBuilder);
    
                        // Define some fields
                        FieldBuilder nameField =
                            personTypeBuilder.DefineField(
                                "name",
                                typeof(string),
                                FieldAttributes.Private);
                        FieldBuilder ageField =
                            personTypeBuilder.DefineField(
                                "age",
                                typeof(int),
                                FieldAttributes.Private);
    
                        // Define the public properties
                        MethodBuilder get_Name;
                        MethodBuilder get_Age;
                        PropertyBuilder nameProperty = CreateProperty(personTypeBuilder, "Name", nameField, out get_Name);
                        PropertyBuilder ageProperty = CreateProperty(personTypeBuilder, "Age", ageField, out get_Age);
    
                        // Override ToString
                        MethodBuilder toString = personTypeBuilder.DefineMethod(
                            "ToString",
                            MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                            typeof(string),
                            Type.EmptyTypes);
    
                        MethodInfo stringFormat = typeof(string).GetMethod(
                            "Format",
                            BindingFlags.Static | BindingFlags.Public,
                            null,
                            new Type[] { typeof(string), typeof(object), typeof(object) },
                            null);
    
                        ILGenerator toStringIL = toString.GetILGenerator();
                        toStringIL.Emit(OpCodes.Ldstr, "Person[Name={0},Age={1}]");
                        toStringIL.Emit(OpCodes.Ldarg_0);
                        toStringIL.Emit(OpCodes.Call, get_Name);
                        toStringIL.Emit(OpCodes.Ldarg_0);
                        toStringIL.Emit(OpCodes.Call, get_Age);
                        toStringIL.Emit(OpCodes.Box, typeof(int));
                        toStringIL.Emit(OpCodes.Call, stringFormat);
                        toStringIL.Emit(OpCodes.Ret);
    
                        personType = personTypeBuilder.CreateType();
                    }
    
                    return personType;
                }
    
                private static PropertyBuilder CreateProperty(TypeBuilder typeBuilder, string propertyName, FieldBuilder backingField, out MethodBuilder getter)
                {
                    Type propertyType = backingField.FieldType;
                    PropertyBuilder property = typeBuilder.DefineProperty(
                        propertyName,
                        PropertyAttributes.None,
                        propertyType,
                        Type.EmptyTypes);
    
                    Type dmaType = typeof(DataMemberAttribute);
                    CustomAttributeBuilder dataMemberAttribute = new CustomAttributeBuilder(
                        dmaType.GetConstructor(Type.EmptyTypes),
                        new object[0],
                        new PropertyInfo[] { dmaType.GetProperty("Name") },
                        new object[] { propertyName });
                    property.SetCustomAttribute(dataMemberAttribute);
    
                    MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
    
                    MethodBuilder getMethod = typeBuilder.DefineMethod("get_" + propertyName, getSetAttr, propertyType, Type.EmptyTypes);
                    MethodBuilder setMethod = typeBuilder.DefineMethod("set_" + propertyName, getSetAttr, null, new Type[] { propertyType });
    
                    getter = getMethod;
    
                    ILGenerator getIL = getMethod.GetILGenerator();
                    getIL.Emit(OpCodes.Ldarg_0);
                    getIL.Emit(OpCodes.Ldfld, backingField);
                    getIL.Emit(OpCodes.Ret);
    
                    ILGenerator setIL = setMethod.GetILGenerator();
                    setIL.Emit(OpCodes.Ldarg_0);
                    setIL.Emit(OpCodes.Ldarg_1);
                    setIL.Emit(OpCodes.Stfld, backingField);
                    setIL.Emit(OpCodes.Ret);
    
                    property.SetSetMethod(setMethod);
                    property.SetGetMethod(getMethod);
    
                    return property;
                }
            }
        }
    
    

     


    Carlos Figueira
    Monday, September 19, 2011 3:00 AM

All replies

  • Can you try using streams or the generic message type(contract is embedded in the body and the type is populated in the header and based on this you deserialize it according to the type in the header)
    Regards, Madhukar Gilla
    Saturday, September 17, 2011 6:31 PM
  • As long as you have a reference to the dynamically-generated type (either passed to the resolver, or created by the resolver itself), the resolver should be able to work out fine. The example below shows a reflection.emit type being passed as a member of another object to a service.

        public class Post_79533008_cb7f_478d_9f34_24ed85f5cd51
        {
            [DataContract]
            public class MyHolder
            {
                [DataMember]
                public object Value;
    
                public override string ToString()
                {
                    return string.Format("MyHolder[Value={0}]", this.Value);
                }
            }
            [ServiceContract]
            public interface ITest
            {
                [OperationContract]
                MyHolder EchoHolder(MyHolder holder);
            }
            public class Service : ITest
            {
                public MyHolder EchoHolder(MyHolder holder)
                {
                    return holder;
                }
            }
            private static void SetResolver(ServiceEndpoint endpoint)
            {
                foreach (var operation in endpoint.Contract.Operations)
                {
                    DataContractSerializerOperationBehavior dcsob = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
                    if (dcsob != null)
                    {
                        dcsob.DataContractResolver = new DynamicTypeResolver(ReflectionEmitHelper.CreatePersonType());
                    }
                }
            }
            public static void Test()
            {
                string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
                ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
                ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
                SetResolver(endpoint);
                host.Open();
                Console.WriteLine("Host opened");
    
                ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
                SetResolver(factory.Endpoint);
                ITest proxy = factory.CreateChannel();
    
                Type personType = ReflectionEmitHelper.CreatePersonType();
                object person = Activator.CreateInstance(personType);
                personType.GetProperty("Name").SetValue(person, "John Doe", null);
                personType.GetProperty("Age").SetValue(person, 22, null);
                Console.WriteLine("Person: {0}", person);
    
                MyHolder holder = new MyHolder { Value = person };
                Console.WriteLine("Sending holder over the wire: {0}", holder);
                var newHolder = proxy.EchoHolder(holder);
                Console.WriteLine("Received holder over the wire: {0}", newHolder);
    
                ((IClientChannel)proxy).Close();
                factory.Close();
    
                Console.Write("Press ENTER to close the host");
                Console.ReadLine();
                host.Close();
            }
    
            class DynamicTypeResolver : DataContractResolver
            {
                Type dynamicType;
                public DynamicTypeResolver(Type dynamicType)
                {
                    this.dynamicType = dynamicType;
                }
    
                public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
                {
                    if (typeNamespace == "http://dynamic/" + ReflectionEmitHelper.AssemblyName && typeName == this.dynamicType.Name)
                    {
                        return this.dynamicType;
                    }
                    else
                    {
                        return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null);
                    }
                }
    
                public override bool TryResolveType(Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
                {
                    if (type.Assembly.GetName().Name == ReflectionEmitHelper.AssemblyName)
                    {
                        XmlDictionary dic = new XmlDictionary();
                        typeName = dic.Add(type.Name);
                        typeNamespace = dic.Add("http://dynamic/" + ReflectionEmitHelper.AssemblyName);
                        return true;
                    }
                    else
                    {
                        return knownTypeResolver.TryResolveType(type, declaredType, null, out typeName, out typeNamespace);
                    }
                }
            }
    
            static class ReflectionEmitHelper
            {
                public const string AssemblyName = "MyReflectionEmitAssembly";
                static Type personType;
    
                internal static Type CreatePersonType()
                {
                    if (personType == null)
                    {
                        AppDomain myDomain = AppDomain.CurrentDomain;
                        AssemblyName myAsmName = new AssemblyName(AssemblyName);
                        AssemblyBuilder myAssembly =
                            myDomain.DefineDynamicAssembly(myAsmName,
                                AssemblyBuilderAccess.RunAndSave);
    
                        ModuleBuilder myModule =
                            myAssembly.DefineDynamicModule(myAsmName.Name,
                               myAsmName.Name + ".dll");
    
                        // public class Person
                        TypeBuilder personTypeBuilder =
                            myModule.DefineType("Person", TypeAttributes.Public);
    
                        // Add [DataContract] to the type
                        Type dcaType = typeof(DataContractAttribute);
                        CustomAttributeBuilder dataContractBuilder = new CustomAttributeBuilder(
                            dcaType.GetConstructor(Type.EmptyTypes),
                            new object[0],
                            new PropertyInfo[] { dcaType.GetProperty("Name"), dcaType.GetProperty("Namespace") },
                            new object[] { "Person", "http://my.dynamic.namespace" });
                        personTypeBuilder.SetCustomAttribute(dataContractBuilder);
    
                        // Define some fields
                        FieldBuilder nameField =
                            personTypeBuilder.DefineField(
                                "name",
                                typeof(string),
                                FieldAttributes.Private);
                        FieldBuilder ageField =
                            personTypeBuilder.DefineField(
                                "age",
                                typeof(int),
                                FieldAttributes.Private);
    
                        // Define the public properties
                        MethodBuilder get_Name;
                        MethodBuilder get_Age;
                        PropertyBuilder nameProperty = CreateProperty(personTypeBuilder, "Name", nameField, out get_Name);
                        PropertyBuilder ageProperty = CreateProperty(personTypeBuilder, "Age", ageField, out get_Age);
    
                        // Override ToString
                        MethodBuilder toString = personTypeBuilder.DefineMethod(
                            "ToString",
                            MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                            typeof(string),
                            Type.EmptyTypes);
    
                        MethodInfo stringFormat = typeof(string).GetMethod(
                            "Format",
                            BindingFlags.Static | BindingFlags.Public,
                            null,
                            new Type[] { typeof(string), typeof(object), typeof(object) },
                            null);
    
                        ILGenerator toStringIL = toString.GetILGenerator();
                        toStringIL.Emit(OpCodes.Ldstr, "Person[Name={0},Age={1}]");
                        toStringIL.Emit(OpCodes.Ldarg_0);
                        toStringIL.Emit(OpCodes.Call, get_Name);
                        toStringIL.Emit(OpCodes.Ldarg_0);
                        toStringIL.Emit(OpCodes.Call, get_Age);
                        toStringIL.Emit(OpCodes.Box, typeof(int));
                        toStringIL.Emit(OpCodes.Call, stringFormat);
                        toStringIL.Emit(OpCodes.Ret);
    
                        personType = personTypeBuilder.CreateType();
                    }
    
                    return personType;
                }
    
                private static PropertyBuilder CreateProperty(TypeBuilder typeBuilder, string propertyName, FieldBuilder backingField, out MethodBuilder getter)
                {
                    Type propertyType = backingField.FieldType;
                    PropertyBuilder property = typeBuilder.DefineProperty(
                        propertyName,
                        PropertyAttributes.None,
                        propertyType,
                        Type.EmptyTypes);
    
                    Type dmaType = typeof(DataMemberAttribute);
                    CustomAttributeBuilder dataMemberAttribute = new CustomAttributeBuilder(
                        dmaType.GetConstructor(Type.EmptyTypes),
                        new object[0],
                        new PropertyInfo[] { dmaType.GetProperty("Name") },
                        new object[] { propertyName });
                    property.SetCustomAttribute(dataMemberAttribute);
    
                    MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
    
                    MethodBuilder getMethod = typeBuilder.DefineMethod("get_" + propertyName, getSetAttr, propertyType, Type.EmptyTypes);
                    MethodBuilder setMethod = typeBuilder.DefineMethod("set_" + propertyName, getSetAttr, null, new Type[] { propertyType });
    
                    getter = getMethod;
    
                    ILGenerator getIL = getMethod.GetILGenerator();
                    getIL.Emit(OpCodes.Ldarg_0);
                    getIL.Emit(OpCodes.Ldfld, backingField);
                    getIL.Emit(OpCodes.Ret);
    
                    ILGenerator setIL = setMethod.GetILGenerator();
                    setIL.Emit(OpCodes.Ldarg_0);
                    setIL.Emit(OpCodes.Ldarg_1);
                    setIL.Emit(OpCodes.Stfld, backingField);
                    setIL.Emit(OpCodes.Ret);
    
                    property.SetSetMethod(setMethod);
                    property.SetGetMethod(getMethod);
    
                    return property;
                }
            }
        }
    
    

     


    Carlos Figueira
    Monday, September 19, 2011 3:00 AM
  • Carlos,

    Your post is very helpful as I'm also trying to return an object from a WCF service whose class is dynamically generated within the service (which is hosted in an IIS web service).  However, I can't quite figure out how to inject the DynamicClassResolver.  Can you recommend a resource that will provide a deep understanding of how the DataContractResolver works?  I haven't found the MSDN documentation to be sufficient.

    Thanks!

    Tuesday, October 25, 2011 5:27 AM
  • I almost had the same problem. I had nearly 40 to 50 legacy and new wcf and web services hosted on different clients network.  I should talk to the service dynamically without getting Proxy (Reference.cs).

    Main Problem is when converting my namespaces to client namespaces.

    For example:- client namespace is ClientWebApplication.Proxy

    My Namespace is GenericSol.Poc, I am using Reflection to get the MethodInfo and PropertyInfo, when I say "var returnValue = targetMethodInfo.Invoke(proxyInstance, argumentValues);" then I will get error. This error won't come for simple types but for complex types this error is coming. Client has complextype as parameter for operationcontract or webmethod, each complextype has 30 to 40 complextype's inside. My Demo Code as follows,

    CompilerResults compilerResults = null;
    MethodInfo targetMethodInfo = null;
    object proxyInstance = GetProxyInstance(ref compilerResults);
                targetMethodInfo = proxyInstance.GetType().GetInterface("IService1").GetMethod("GetTestDataUsingDataContract");
                ParameterInfo [] parInfo = targetMethodInfo.GetParameters();
    Object[] objArgs = new Object[parInfo.Length];
                Object[] objValues = new Object[parInfo.Length];
                
                #region "Input Parameters"
                IOrderedDictionary arguments = new OrderedDictionary();
                ParameterInfo[] p = targetMethodInfo.GetParameters();
                for (int i = 0; i < p.Length; i++)
                {
                    if (p[i].Name == "i")
                        Response.Write("Test");                    
                }
                CompositeType Obj = new CompositeType();
                Obj.BoolValue = true;
                Obj.StringValue = "Test";
                arguments.Add("i", 100);
                arguments.Add("composite", Obj);
                arguments.Add("str", "Test");
                Proxy.Employee emp = new Proxy.Employee();
                emp.EmpNo = 123;
                emp.EmpName = "Test";
                Obj.EmployeeValue = emp;
                #endregion "Input Parameters"
                parInfo.CopyTo(objArgs, 0);
                #region "Validate And Sort Method Arguments"
                ParameterInfo[] parameters = proxyInstance.GetType().GetMethod("GetTestDataUsingDataContract").GetParameters();
                OrderedDictionary valueList = new OrderedDictionary();
                for (int paramIndex = 0; paramIndex < parameters.Length; paramIndex++)
                {
                    bool found = false;
                    foreach (DictionaryEntry valueEntry in arguments)
                    {
                        if (parameters[paramIndex].Name.Equals(valueEntry.Key.ToString()))
                        {
                            found = true;
                            TypeConverter converter = TypeDescriptor.GetConverter(parameters[paramIndex].ParameterType);
                            if (converter.CanConvertFrom(valueEntry.Value.GetType()))
                            {
                                valueList.Add(valueEntry.Key, converter.ConvertFrom(valueEntry.Value));
                            }
                            else if (converter.CanConvertFrom(Type.GetType("System.String")))
                            {
                                valueList.Add(valueEntry.Key, converter.ConvertFrom(valueEntry.Value.ToString()));
                            }
                            else if(valueEntry.Value.GetType().Module.ScopeName != "CommonLanguageRuntimeLibrary")
                            {
                                valueList.Add(valueEntry.Key, valueEntry.Value);
                            }
                        }
                    }
                    if (!found)
                    {
                        throw new ArgumentException("Argument Not Found");
                    }
                }
                arguments.Clear();
                foreach (DictionaryEntry entry in valueList)
                {
                    arguments.Add(entry.Key, entry.Value);
                }
                #endregion "Validate And Sort Method Arguments"
                #region "Invoke Call"
                object[] argumentValues = new object[arguments.Count];
                arguments.Values.CopyTo(argumentValues, 0);
                var returnValue = targetMethodInfo.Invoke(proxyInstance, argumentValues);
    I just want to call a method dynamically without proxy, for that method fill the parameters for both complex and simple. If complextype, then it has 30 to 40 sub complextypes.  Any suggestion
    Thanks In Advance, 


    SivaNarayana

    Friday, November 29, 2013 7:06 AM
  • I almost had the same problem. I had nearly 40 to 50 legacy and new wcf and web services hosted on different clients network.  I should talk to the service dynamically without getting Proxy (Reference.cs).

    Main Problem is when converting my namespaces to client namespaces.

    For example:- client namespace is ClientWebApplication.Proxy

    My Namespace is GenericSol.Poc, I am using Reflection to get the MethodInfo and PropertyInfo, when I say "var returnValue = targetMethodInfo.Invoke(proxyInstance, argumentValues);" then I will get error. This error won't come for simple types but for complex types this error is coming. Client has complextype as parameter for operationcontract or webmethod, each complextype has 30 to 40 complextype's inside. My Demo Code as follows,

    CompilerResults compilerResults = null;
    MethodInfo targetMethodInfo = null;
    object proxyInstance = GetProxyInstance(ref compilerResults);
                targetMethodInfo = proxyInstance.GetType().GetInterface("IService1").GetMethod("GetTestDataUsingDataContract");
                ParameterInfo [] parInfo = targetMethodInfo.GetParameters();
    Object[] objArgs = new Object[parInfo.Length];
                Object[] objValues = new Object[parInfo.Length];
                
                #region "Input Parameters"
                IOrderedDictionary arguments = new OrderedDictionary();
                ParameterInfo[] p = targetMethodInfo.GetParameters();
                for (int i = 0; i < p.Length; i++)
                {
                    if (p[i].Name == "i")
                        Response.Write("Test");                    
                }
                CompositeType Obj = new CompositeType();
                Obj.BoolValue = true;
                Obj.StringValue = "Test";
                arguments.Add("i", 100);
                arguments.Add("composite", Obj);
                arguments.Add("str", "Test");
                Proxy.Employee emp = new Proxy.Employee();
                emp.EmpNo = 123;
                emp.EmpName = "Test";
                Obj.EmployeeValue = emp;
                #endregion "Input Parameters"
                parInfo.CopyTo(objArgs, 0);
                #region "Validate And Sort Method Arguments"
                ParameterInfo[] parameters = proxyInstance.GetType().GetMethod("GetTestDataUsingDataContract").GetParameters();
                OrderedDictionary valueList = new OrderedDictionary();
                for (int paramIndex = 0; paramIndex < parameters.Length; paramIndex++)
                {
                    bool found = false;
                    foreach (DictionaryEntry valueEntry in arguments)
                    {
                        if (parameters[paramIndex].Name.Equals(valueEntry.Key.ToString()))
                        {
                            found = true;
                            TypeConverter converter = TypeDescriptor.GetConverter(parameters[paramIndex].ParameterType);
                            if (converter.CanConvertFrom(valueEntry.Value.GetType()))
                            {
                                valueList.Add(valueEntry.Key, converter.ConvertFrom(valueEntry.Value));
                            }
                            else if (converter.CanConvertFrom(Type.GetType("System.String")))
                            {
                                valueList.Add(valueEntry.Key, converter.ConvertFrom(valueEntry.Value.ToString()));
                            }
                            else if(valueEntry.Value.GetType().Module.ScopeName != "CommonLanguageRuntimeLibrary")
                            {
                                valueList.Add(valueEntry.Key, valueEntry.Value);
                            }
                        }
                    }
                    if (!found)
                    {
                        throw new ArgumentException("Argument Not Found");
                    }
                }
                arguments.Clear();
                foreach (DictionaryEntry entry in valueList)
                {
                    arguments.Add(entry.Key, entry.Value);
                }
                #endregion "Validate And Sort Method Arguments"
                #region "Invoke Call"
                object[] argumentValues = new object[arguments.Count];
                arguments.Values.CopyTo(argumentValues, 0);
                var returnValue = targetMethodInfo.Invoke(proxyInstance, argumentValues);
    I just want to call a method dynamically without proxy, for that method fill the parameters for both complex and simple. If complextype, then it has 30 to 40 sub complextypes.  Any suggestion
    Thanks In Advance, 


    SivaNarayana

    Friday, November 29, 2013 7:08 AM
  • I almost had the same problem. I had nearly 40 to 50 legacy and new wcf and web services hosted on different clients network.  I should talk to the service dynamically without getting Proxy (Reference.cs).

    Main Problem is when converting my namespaces to client namespaces.

    For example:- client namespace is ClientWebApplication.Proxy

    My Namespace is GenericSol.Poc, I am using Reflection to get the MethodInfo and PropertyInfo, when I say "var returnValue = targetMethodInfo.Invoke(proxyInstance, argumentValues);" then I will get error. This error won't come for simple types but for complex types this error is coming. Client has complextype as parameter for operationcontract or webmethod, each complextype has 30 to 40 complextype's inside. My Demo Code as follows,

    CompilerResults compilerResults = null;
    MethodInfo targetMethodInfo = null;
    object proxyInstance = GetProxyInstance(ref compilerResults);
                targetMethodInfo = proxyInstance.GetType().GetInterface("IService1").GetMethod("GetTestDataUsingDataContract");
                ParameterInfo [] parInfo = targetMethodInfo.GetParameters();
    Object[] objArgs = new Object[parInfo.Length];
                Object[] objValues = new Object[parInfo.Length];
                
                #region "Input Parameters"
                IOrderedDictionary arguments = new OrderedDictionary();
                ParameterInfo[] p = targetMethodInfo.GetParameters();
                for (int i = 0; i < p.Length; i++)
                {
                    if (p[i].Name == "i")
                        Response.Write("Test");                    
                }
                CompositeType Obj = new CompositeType();
                Obj.BoolValue = true;
                Obj.StringValue = "Test";
                arguments.Add("i", 100);
                arguments.Add("composite", Obj);
                arguments.Add("str", "Test");
                Proxy.Employee emp = new Proxy.Employee();
                emp.EmpNo = 123;
                emp.EmpName = "Test";
                Obj.EmployeeValue = emp;
                #endregion "Input Parameters"
                parInfo.CopyTo(objArgs, 0);
                #region "Validate And Sort Method Arguments"
                ParameterInfo[] parameters = proxyInstance.GetType().GetMethod("GetTestDataUsingDataContract").GetParameters();
                OrderedDictionary valueList = new OrderedDictionary();
                for (int paramIndex = 0; paramIndex < parameters.Length; paramIndex++)
                {
                    bool found = false;
                    foreach (DictionaryEntry valueEntry in arguments)
                    {
                        if (parameters[paramIndex].Name.Equals(valueEntry.Key.ToString()))
                        {
                            found = true;
                            TypeConverter converter = TypeDescriptor.GetConverter(parameters[paramIndex].ParameterType);
                            if (converter.CanConvertFrom(valueEntry.Value.GetType()))
                            {
                                valueList.Add(valueEntry.Key, converter.ConvertFrom(valueEntry.Value));
                            }
                            else if (converter.CanConvertFrom(Type.GetType("System.String")))
                            {
                                valueList.Add(valueEntry.Key, converter.ConvertFrom(valueEntry.Value.ToString()));
                            }
                            else if(valueEntry.Value.GetType().Module.ScopeName != "CommonLanguageRuntimeLibrary")
                            {
                                valueList.Add(valueEntry.Key, valueEntry.Value);
                            }
                        }
                    }
                    if (!found)
                    {
                        throw new ArgumentException("Argument Not Found");
                    }
                }
                arguments.Clear();
                foreach (DictionaryEntry entry in valueList)
                {
                    arguments.Add(entry.Key, entry.Value);
                }
                #endregion "Validate And Sort Method Arguments"
                #region "Invoke Call"
                object[] argumentValues = new object[arguments.Count];
                arguments.Values.CopyTo(argumentValues, 0);
                var returnValue = targetMethodInfo.Invoke(proxyInstance, argumentValues);
    I just want to call a method dynamically without proxy, for that method fill the parameters for both complex and simple. If complextype, then it has 30 to 40 sub complextypes.  Any suggestion
    Thanks In Advance, 


    SivaNarayana

    Friday, November 29, 2013 7:08 AM
  • any suggestions on the issue/approach?

    SivaNarayana

    Friday, November 29, 2013 8:32 AM
  • any suggestions?

    SivaNarayana

    Friday, November 29, 2013 8:33 AM