您的位置:首页 > 其它

终于搞定无参“动态调用WebService方法”,其实很简单,大家还是要有信心,还是要有琢磨的精神。

2012-05-17 17:26 357 查看
终于搞定“动态调用WebService方法”:

我在学习 动态调用WebService方法时看到很多网友在调用函数(其实往往是“无参”函数)时得到一个错误:

未将对象引用设置到对象的实例。

这个错误很常见,貌似不好处理,没明白的人不知所云,所以这里提醒我们自己:凡是都要有信心。

导致大家以为动态调用没有成功,对整个动态调用方法都失去的信心,其实不然。

我研究了 MethodInfo的这个方法Invoke,发现通过拼凑方法可以变相成功。

为了方便学习的人,把所涉及到的内容都提上来。第一次写博客,我也是参考了N多网友的成功经验,一并谢谢了。

请大家注意下面这句:
//我就是添加了下面的语句,就算是完全解决了调用WebService中函数带参和不带参的方法,虽然我对一些理论不是很清楚,但是用拼凑的方法调试,到是成功了。

WebServiceHelper.cs

using System.Net;

using System.CodeDom;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using DevExpress.XtraGrid;

using DevExpress.XtraGrid.Views.Base;

using System.Data.Common;

using CrystalDecisions.Shared;

using CrystalDecisions.CrystalReports.Engine;

using System.IO;

using System.Drawing.Printing;

using System.Drawing.Imaging;

using Microsoft.Reporting.WinForms;

using System.Configuration;

using System.Web.Services;

using System.Web.Services.Description;

using Microsoft.CSharp;

using System.Reflection;

using System.CodeDom.Compiler;

namespace Print_ACCS

{

public static class WebServiceHelper

{

//动态调用web服务

public static object InvokeWebService(string url, string methodname, object[] args)

{

return WebServiceHelper.InvokeWebService(url, null, methodname, args);

}

public static object InvokeWebService(string url, string classname, string methodname, object[] args)

{

string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";

if ((classname == null) || (classname == ""))

{

classname = WebServiceHelper.GetWsClassName(url);

}

try

{

//获取WSDL

WebClient wc = new WebClient();

Stream stream = wc.OpenRead(url + "?WSDL");

ServiceDescription sd = ServiceDescription.Read(stream);

ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();

sdi.AddServiceDescription(sd, "", "");

CodeNamespace cn = new CodeNamespace(@namespace);

//生成客户端代理类代码

CodeCompileUnit ccu = new CodeCompileUnit();

ccu.Namespaces.Add(cn);

sdi.Import(cn, ccu);

CSharpCodeProvider csc = new CSharpCodeProvider();

ICodeCompiler icc = csc.CreateCompiler();

//设定编译参数

CompilerParameters cplist = new CompilerParameters();

cplist.GenerateExecutable = false;

cplist.GenerateInMemory = true;

cplist.ReferencedAssemblies.Add("System.dll");

cplist.ReferencedAssemblies.Add("System.XML.dll");

cplist.ReferencedAssemblies.Add("System.Web.Services.dll");

cplist.ReferencedAssemblies.Add("System.Data.dll");

//编译代理类

CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);

if (true == cr.Errors.HasErrors)

{

System.Text.StringBuilder sb = new System.Text.StringBuilder();

foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors)

{

sb.Append(ce.ToString());

sb.Append(System.Environment.NewLine);

}

throw new Exception(sb.ToString());

}

//生成代理实例,并调用方法

System.Reflection.Assembly assembly = cr.CompiledAssembly;

Type t = assembly.GetType(@namespace + "." + classname, true, true);

object obj = Activator.CreateInstance(t);

System.Reflection.MethodInfo mi = t.GetMethod(methodname);

//return mi.Invoke(obj, args);//我就是添加了下面的语句,就算是完全解决了调用WebService中函数带参和不带参的方法,虽然我对一些理论不是很清楚,但是用拼凑的方法调试总是解决了,还是早点把这个程序弄完吧。

if (args[0] != "")

return mi.Invoke(obj, args);

else

//Invoke(obj, BindingFlags.Default, new MyBinder(), new Object[] { (int)32, (int)32 }, CultureInfo.CurrentCulture);//这个是msdn上的,比较复杂有时间再琢磨。

return mi.Invoke(obj, BindingFlags.Default, null, null, null);

}

catch (Exception ex)

{

throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));

}

}

private static string GetWsClassName(string wsUrl)

{

string[] parts = wsUrl.Split('/');

string[] pps = parts[parts.Length - 1].Split('.');

return pps[0];

}

}

}

在主程序中增加:

public static string WebSer_url = ConfigurationSettings.AppSettings["WebService_url"];

在配置文件app.config中:增加WebService_url

< ?xml version="1.0"?>

< configuration>

<configSections>

</configSections>

<appSettings>

<add key="WebService_url" value="http://192.168.3.117/ws/Service.asmx" />

</appSettings>

< /configuration>

WebService的代码:

using System;

using System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Data;

using System.Configuration;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Data.OracleClient;

using System.Text;

namespace handsome

{

[WebService(Namespace = "http://www.xxxx.com/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

//若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。

// [System.Web.Script.Services.ScriptService]

public class Service : System.Web.Services.WebService

{

public Service()

{

//如果使用设计的组件,请取消注释以下行

//InitializeComponent();

}

private void InitializeComponent()

{

}

[WebMethod]

public string HelloWorld1()

{

myheader.isValid(out msg);

return "Hello World1";

}

[SoapHeader("myheader")]

[WebMethod]

public string HelloWorld2()

{

return "Hello World2";

}

[WebMethod(Description = "返回销售发票的条码")]

public string getbarcode_byINV_NO(string str_no)

{

return DbUtil_XSFP.getbarcode_byINV_NO(str_no);

}

}

}

具体调用时:

string st="";//为默认空变量,或者具体数值

File.WriteAllText(reportPath + file_barcode, (string)WebServiceHelper.InvokeWebService(logfrm.WebSer_url, "getbarcode_byINV_NO", new string[] { st }), Encoding.Default);

或者:

dev_gridcontr.DataSource = (DataTable)WebServiceHelper.InvokeWebService(logfrm.WebSer_url, "Get_XSFP_TIME", new string[] { "" });



object result = WebServiceHelper.InvokeWebService(url, "getbarcode_byINV_NO", new string[] { "CZXSFP-1202000088" });
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: