[C#] 取得.net WebService(.asmx) 的函式(Method)名稱及輸入和輸出的參數和型態

2013-06-11

上一篇我們談到 取得.net WebService(.asmx) 的函式(Method)名稱 

不過只有取得名字是不夠的,這一篇我們來列出除了名稱之外,輸入及輸出參數的名稱和型別

看一下 Service 所開的 輸入跟輸出型態

2013-06-11_150524

有三個method 各自都有自己的Input(紅色線條),還有 Output (藍色線條)

我們要透過WSDL 將他取出來..

因為資料比較多,所以建立一個class 來做整理..

using System.Collections.Generic;
 
namespace TestGetWebServiceInfo
{
    public class MethodInfo
    {
        /// <summary>
        /// 主method 名稱
        /// </summary>
        public string MethodName { get; set; }
 
        /// <summary>
        /// 在WSDL 中 InputMessage的名稱 通常為 [MethodName]SoapIn
        /// </summary>
        public string InputMessageName { get; set; }
 
        /// <summary>
        /// 在WSDL 中 OutputMessage的名稱 通常為 [MethodName]SoapOut
        /// </summary>
        public string OutputMessageName { get; set; }
 
        /// <summary>
        /// 輸入的參數們 Key名稱 , Value為型別
        /// </summary>
        public Dictionary<string,string> InputParameters { get; set; }
 
        /// <summary>
        /// 輸出的參數們 Key名稱 , Value為型別
        /// </summary>
        public Dictionary<string, string> OutParameters { get; set; }
        public string Desc { get; set; }
 
        public MethodInfo()
        {
            InputParameters=new Dictionary<string, string>();
            OutParameters=new Dictionary<string, string>();
        }
    }
}

之所以能夠取到輸入或是輸出的型別是因為..


2013-06-11_151638




來做個簡單的解釋 , 在這份WSDL 文件中 首先有一個method 叫做 GetVersion 則他的輸入參數 message 通常名為 GetVersionSoapIn


之後可以取得他的參數是被放在上面 GetVersion 中騎進去看發現他的 sequence 裡面只有一個名為token 的element 型別為 s:string ..


所以就可以知道 他的輸入參數為一個叫做 token 的 string .


在看一個輸出範例


2013-06-11_152229


一個叫做 GetContactBook的method 其輸出通常為 GetContactBookSoapOut 然後取得他的回應參數被定義在 tns:GetContactBookResponse 中.


參照上去其GetContactBookResponse 中裡面有一個參數輸出(輸出當然只會有一個) 為ContactBook的物件型態..


簡單講解一下了..接下來就來看Code :



 
        /// <summary>
        /// 透過網址取得資料後 並且讀為 GeServiceDescriptionFromServicePath
        /// </summary>
        /// <param name="servicePath"></param>
        /// <returns></returns>
        private ServiceDescription GeServiceDescriptionFromServicePath(string servicePath)
        {
            if (!servicePath.ToLower().Contains("?wsdl"))
            {
                servicePath = servicePath + "?wsdl";
            }
 
            var wc = new WebClient();
            wc.Encoding = UTF8Encoding.UTF8;
            byte[] byteArray = Encoding.UTF8.GetBytes(wc.DownloadString(servicePath));
            var stream = new MemoryStream(byteArray);
            return ServiceDescription.Read(stream);
        }
 
 
        /// <summary>
        /// 取得 Parameters 
        /// </summary>
        /// <param name="serviceDescription"></param>
        /// <param name="messagePartName"></param>
        /// <returns></returns>
        private static Dictionary<string, string> GetParameters(ServiceDescription serviceDescription, string messagePartName)
        {
            var types = serviceDescription.Types;
            var xmlSchema = types.Schemas[0];
            return (from schemaElement in xmlSchema.Items.OfType<XmlSchemaElement>() where schemaElement.Name == messagePartName select schemaElement.SchemaType).OfType<XmlSchemaComplexType>().Select(complexType => complexType.Particle).OfType<XmlSchemaSequence>().SelectMany(sequence => sequence.Items.Cast<XmlSchemaElement>()).ToDictionary(childElement => childElement.Name, childElement => childElement.SchemaTypeName.Name);
        }
 
        /// <summary>
        /// 取得所有的Method Details
        /// </summary>
        /// <param name="serviceDescription"></param>
        /// <returns></returns>
        public MethodInfo[] GetMethodInfos(ServiceDescription serviceDescription)
        {
            var res = new List<MethodInfo>();
 
            foreach (PortType portType in serviceDescription.PortTypes)
            {
                foreach (Operation operation in portType.Operations)
                {
 
                    var me = new MethodInfo();
                    me.MethodName = operation.Name;
                    me.InputMessageName = operation.Messages.Input.Message.Name;
                    me.OutputMessageName = operation.Messages.Output.Message.Name;
 
                    //注1
                    me.InputParameters = GetParameters(serviceDescription, serviceDescription.Messages[me.InputMessageName].Parts[0].Element.Name);
                    me.OutParameters = GetParameters(serviceDescription, serviceDescription.Messages[me.OutputMessageName].Parts[0].Element.Name);
 
                    if (operation.DocumentationElement != null)
                        me.Desc = operation.DocumentationElement.InnerText;
 
                    res.Add(me);
                }
            }
 
 
            return res.ToArray();
        }
 
 
 
        protected void btnGetMethodDetails_Click(object sender, EventArgs e)
        {
            var serviceDesc = GeServiceDescriptionFromServicePath(txtWebServicePath.Text);
 
            //取得所有Method Name .
            var allMethodInfos = GetMethodInfos(serviceDesc);
            ltlResult.Text = "";
            foreach (var methodInfo in allMethodInfos)
            {
                ltlResult.Text += "Method Name : <span style='color:red'>" + methodInfo.MethodName + "</span><br />";
                ltlResult.Text += "Input Parameters(傳入參數) : " + "<br />";
                foreach (var param in methodInfo.InputParameters)
                {
                    ltlResult.Text += param.Key + " : " + param.Value + "<br />";
                }
 
                ltlResult.Text += "Output Parameters(傳出參數) : " + "<br />";
                foreach (var param in methodInfo.OutParameters)
                {
                    ltlResult.Text += param.Key + " : " + param.Value + "<br />";
                }
                ltlResult.Text += "<hr />";
 
            }
 
        }


結果:


2013-06-11_152819


Source :


有需要再自行改寫搂


當麻許的超技八 2014 | Donma Hsu Design.