簡體   English   中英

從Web服務獲取自定義類

[英]Get Custom Class from webservices

調用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;
        }
    }
}

+ Page_Load函數:

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_Role對象)。 // ================================================ ===================================== // ========== ================================================== =============================================== ================================================== ========================================================作為Selalu_Ingin_Belajar的回答,我可以從網絡服務中獲得價值,並可以很好地滿足客戶的要求。

對象yourObject =新的對象();

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

在它旁邊,當我申請另一個項目時,它顯示另一個錯誤:參數計數不匹配。 如果我使用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]));
    }

這樣,通過傳遞對象SetupLicenseRowsValues類很容易從webClient調用。 現在,我必須手動將參數傳遞給WebServices。不要使用此生成文件。

客戶:

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並希望您的響應具有期望的“結構”,但不知道真實類型。 如:

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

只需在您的客戶端項目上單擊鼠標右鍵,然后使用Web/Service Reference ,即可發現該Web Service 提供適當的namespace名稱,然后單擊“確定”。

此過程將基於WSDL公開的Schema在客戶端上自動生成GetRoles方法的Proxy以及您的自定義類類型Cls_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之類的Service Reference來獲取對象的清晰架構。 因為它將自動序列化您的對象,所以您不必擔心序列化的問題。 對不起我的英語:p

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM