C# 从Web服务获取自定义类

C# 从Web服务获取自定义类,c#,asp.net,web-services,asmx,C#,Asp.net,Web Services,Asmx,调用Webservices后,它将向客户端返回一个对象(该对象是一个自定义对象类)。所以,我想把这个对象转换成自定义类 -网络服务: [WebMethod] public Cls_ROLES GetRoles(int firstNum) { Cls_ROLES o = new Cls_ROLES(); o.Role_ID = 2; o.RoleName = "binh"; return o; } -客户: +功能: public object CallWebSe

调用
Webservices
后,它将向客户端返回一个对象(该对象是一个自定义对象类)。所以,我想把这个对象转换成自定义类

-网络服务:

[WebMethod]
public Cls_ROLES GetRoles(int firstNum)
{
    Cls_ROLES o = new Cls_ROLES();
    o.Role_ID = 2;
    o.RoleName = "binh";
    return o;
}
-客户:

+功能:

public object CallWebService(string webServiceAsmxUrl, string serviceName, string methodName, object[] args)
{
    System.Net.WebClient client = new System.Net.WebClient();
    //-Connect To the web service
    using (System.IO.Stream stream = client.OpenRead(webServiceAsmxUrl + "?wsdl"))
    {
        //--Now read the WSDL file describing a service.
        ServiceDescription description = ServiceDescription.Read(stream);
        ///// LOAD THE DOM /////////
        //--Initialize a service description importer.
        ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
        importer.ProtocolName = "Soap12"; // Use SOAP 1.2.
        importer.AddServiceDescription(description, null, null);
        //--Generate a proxy client. importer.Style = ServiceDescriptionImportStyle.Client;
        //--Generate properties to represent primitive values.
        importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
        //--Initialize a Code-DOM tree into which we will import the service.
        CodeNamespace nmspace = new CodeNamespace();
        CodeCompileUnit unit1 = new CodeCompileUnit();
        unit1.Namespaces.Add(nmspace);
        //--Import the service into the Code-DOM tree. This creates proxy code
        //--that uses the service.
        ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
        if (warning == 0) //--If zero then we are good to go
        {
            //--Generate the proxy code 
            CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
            //--Compile the assembly proxy with the appropriate references
            string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };
            CompilerParameters parms = new CompilerParameters(assemblyReferences);
            CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
            //-Check For Errors
            if (results.Errors.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                foreach (CompilerError oops in results.Errors)
                {
                    sb.AppendLine("========Compiler error============");
                    sb.AppendLine(oops.ErrorText);
                }
                throw new System.ApplicationException("Compile Error Occured calling webservice. " + sb.ToString());
            }
            //--Finally, Invoke the web service method 
            Type foundType = null;
            Type[] types = results.CompiledAssembly.GetTypes();
            foreach (Type type in types)
            {
                if (type.BaseType == typeof(System.Web.Services.Protocols.SoapHttpClientProtocol))
                {
                    Console.WriteLine(type.ToString());
                    foundType = type;
                }
            }

            object wsvcClass = results.CompiledAssembly.CreateInstance(foundType.ToString());
            MethodInfo mi = wsvcClass.GetType().GetMethod(methodName);
            object o = new object();
            o=mi.Invoke(wsvcClass, args);
            return o;
        }
        else
        {
            return null;
        }
    }
}
+页面加载功能:

Line 1:object[] args=new object[1];
Line 2:args[0]=1;  
Line 3:o = this.CallWebService("http://localhost:1814/HelloServices/Service.asmx", "Hello", "GetRoles", args);
它将第3行的对象(此对象是自定义对象类)返回给客户端。因此,我想将这个对象转换为自定义类(Cls_角色对象)。 //====================================================================================== //====================================================================================== //====================================================================================== 正如Selalu_Ingin_Belajar的回答,我可以从Web服务中获得对客户端的价值

对象yourObject=新对象()

在它旁边,当我应用到另一个项目时,它显示另一个错误:参数计数不匹配。 如果我通过VisualStudio工具使用AddWebReference。 它将自动生成Reference.cs文件。它包含:

/// <remarks/>
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", RequestNamespace="urn:ALBAPI", ResponseNamespace="urn:ALBAPI")]
    [return: System.Xml.Serialization.SoapElementAttribute("info")]
    public ResponseInfo getSetupLicenseRows(out SetupLicenseRowsValues values) {
        object[] results = this.Invoke("getSetupLicenseRows", new object[0]);
        values = ((SetupLicenseRowsValues)(results[1]));
        return ((ResponseInfo)(results[0]));
    }
现在,它在行错误处显示错误“参数计数不匹配”。
无论如何,谢谢您的帮助

现在,如果我理解正确,并且由于您经历了动态构建代理(而不是使用服务引用)的繁琐工作,这意味着您的用户代码不包含您可能的服务可能返回的任何对象的实际定义

在这种情况下,我看不出有多少方法可以通过静态类型的代码实现这一点。 您可以尝试使用
dynamic
,希望您的响应具有您期望的“结构”,但不知道真正的类型。 例如:


只需使用
Web/Service Reference
,右键单击您的客户端项目,即可发现此
Web服务
。提供适当的
名称空间
名称,然后单击确定


此过程将根据
WSDL

中公开的模式在客户端上自动生成
GetRoles
方法的
Proxy
,以及自定义类类型
Cls\u ROLES
,如果您只想获取对象的每个参数的值,可以使用反射

object yourObject = new object();

foreach (PropertyInfo property in yourObject.GetType().GetProperties())
{           
    object value = property.GetValue(yourObject , null);
    Console.WriteLine("{0} = {1}", property.Name, value);
}

但最好使用Pablo和Furqan所说的服务引用来获得对象的清晰模式。因为它会自动序列化你的对象,所以你不用担心序列化的事情。对不起我的英语:你做了什么?展示你的努力。你到底为什么这样称呼web服务?如果你还在运行.NET 2.0,只需使用服务参考或Web参考。我想说声谢谢,这非常聪明,也很有趣,虽然有点疯狂。@Furqan Safdar:我在3周内就研究过了,如果我们从Web服务返回一个字符串或双精度类型到客户端,这很容易。但是当我们想要返回一个自定义类时,这似乎很难。ThanksThanks bro,我试过并看到它工作得很好。它显示propertyName和value很好。哦,是的,我将进一步研究Serialize。请与我联系,兄弟。ThanksHi兄弟,我有另一个错误。它显示了错误“参数计数不匹配“行错误。我编辑此描述。无论如何感谢您的帮助。感谢bro的建议。因为我的项目需要通过输入地址和端口手动连接到多个服务到Web窗体。系统将保存它们,之后,使用此信息手动连接到Web服务。无法手动添加到visualStudio。因此,我们无法将AddWebReference用作Carlosfemer.com/post/2008/01/…link无法定义使用“dynamic”的类或成员,因为找不到编译器所需的类型“System.Runtime.CompilerServices.DynamicAttribute”。您是否缺少对System.Core.dll的引用?我认为执行它会很困难。因为我们必须更改CallWebservice(..)函数的返回类型。在它旁边是Console.WriteLine(returnValue.Role\u ID);它将显示错误:找不到编译动态表达式所需的一个或多个类型。是否缺少对Microsoft.CSharp.dll和System.Core.dll的引用?谢谢您的帮助我认为您不需要更改CallWebservice函数中的任何内容。你在C#4.0上吗?嗨,兄弟,我在C#4.0上。你能告诉我一些想法吗。谢谢兄弟,现在在测线错误处显示错误“参数计数不匹配”。我在这个描述中编辑了一些东西。
public object CallWebService(string webServiceAsmxUrl, string serviceName, string methodName, object[] args)
        {
            System.Net.WebClient client = new System.Net.WebClient();
            //-Connect To the web service
            using (System.IO.Stream stream = client.OpenRead(webServiceAsmxUrl + "?wsdl"))
            {
                //--Now read the WSDL file describing a service.
                ServiceDescription description = ServiceDescription.Read(stream);
                ///// LOAD THE DOM /////////
                //--Initialize a service description importer.
                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
                importer.ProtocolName = "Soap12"; // Use SOAP 1.2.
                importer.AddServiceDescription(description, null, null);
                //--Generate a proxy client. importer.Style = ServiceDescriptionImportStyle.Client;
                //--Generate properties to represent primitive values.
                importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
                //--Initialize a Code-DOM tree into which we will import the service.
                CodeNamespace nmspace = new CodeNamespace();
                CodeCompileUnit unit1 = new CodeCompileUnit();
                unit1.Namespaces.Add(nmspace);
                //--Import the service into the Code-DOM tree. This creates proxy code
                //--that uses the service.
                ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
                if (warning == 0) //--If zero then we are good to go
                {
                    //--Generate the proxy code 
                    CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
                    //--Compile the assembly proxy with the appropriate references
                    string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };
                    CompilerParameters parms = new CompilerParameters(assemblyReferences);
                    CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
                    //-Check For Errors
                    if (results.Errors.Count > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        foreach (CompilerError oops in results.Errors)
                        {
                            sb.AppendLine("========Compiler error============");
                            sb.AppendLine(oops.ErrorText);
                        }
                        throw new System.ApplicationException("Compile Error Occured calling webservice. " + sb.ToString());
                    }
                    //--Finally, Invoke the web service method 
                    Type foundType = null;
                    Type[] types = results.CompiledAssembly.GetTypes();
                    foreach (Type type in types)
                    {
                        if (type.BaseType == typeof(System.Web.Services.Protocols.SoapHttpClientProtocol))
                        {
                            Console.WriteLine(type.ToString());
                            foundType = type;
                        }
                    }

                    object wsvcClass = results.CompiledAssembly.CreateInstance(foundType.ToString());
                    MethodInfo mi = wsvcClass.GetType().GetMethod(methodName);
                    object o = new object();
                    Line error: o = mi.Invoke(wsvcClass, new object[0]);
                    return o;
                }
                else
                {
                    return null;
                }
            }
        }
public void call()
    {
        string WebserviceUrl = "http://192.168.2.19:3333/ALBAPI.wsdl";
        string serviceName = "ALBAPI";
        string methodName = "getSetupLicenseRows";
        object[] args=new object[0];
        object sSessionID = CallWebService(WebserviceUrl, serviceName, methodName,args);
        foreach (PropertyInfo property in sSessionID.GetType().GetProperties())
        {
            object value = property.GetValue(sSessionID, null);

            Console.WriteLine("{0} = {1}", property.Name, value);
        }

    }
dynamic returnValue = CallWebservice(someEndpoint, someServiceName, ...);
//now you can access all the properties of returnValue, for example:
Console.WriteLine(returnValue.Role_ID);
//but you won't have intellisense, may be error prone, and will prevent you from proper refactoring
object yourObject = new object();

foreach (PropertyInfo property in yourObject.GetType().GetProperties())
{           
    object value = property.GetValue(yourObject , null);
    Console.WriteLine("{0} = {1}", property.Name, value);
}