终于搞定“动态调用WebService方法”:
我在学习 动态调用WebService方法时看到很多网友在调用函数(其实往往是“无参”函数)时得到一个错误:
未将对象引用设置到对象的实例。
这个错误很常见,貌似不好处理,没明白的人不知所云,所以这里提醒我们自己:凡是都要有信心。
导致大家以为动态调用没有成功,对整个动态调用方法都失去的信心,其实不然。
我研究了 MethodInfo的这个方法Invoke,发现通过拼凑方法可以变相成功。
为了方便学习的人,把所涉及到的内容都提上来。第一次写博客,我也是参考了N多网友的成功经验,一并谢谢了。
请大家注意下面这句:
//我就是添加了下面的语句,就算是完全解决了调用WebService中函数带参和不带参的方法,虽然我对一些理论不是很清楚,但是用拼凑的方法调试,到是成功了。
WebServiceHelper.cs
using Sy
stem.Collections.Generic;
using Sy
stem.ComponentModel;
using Sy
stem.Windows.Forms;
using Sy
stem.Runtime.InteropServices;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using Sy
stem.Data.Common;
using CrystalDecisions.Shared;
using CrystalDecisions.CrystalReports.Engine;
using Sy
stem.Drawing.Printing;
using Sy
stem.Drawing.Imaging;
using Microsoft.Reporting.WinForms;
using Sy
stem.Web.Services;
using Sy
stem.Web.Services.Description;
using Microsoft.CSharp;
using Sy
stem.CodeDom.Compiler;
namespace Print_ACCS
{
public static class WebServiceHelper
{
public static object InvokeWebService(string url,string methodname,object[] args)
{
return WebServiceHelper.InvokeWebService(url,null,methodname,args);
}
string @namespace = "EnterpriseServerBase.WebService.DynamicWebCalling";
if ((classname == null) || (classname == ""))
{
classname = WebServiceHelper.GetWsClassName(url);
}
try
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();
//设定编译参数
CompilerP
arameters cplist = new CompilerP
arameters();
cplist.GenerateExecutable = false;
cplist.GenerateInMemory = true;
cplist.ReferencedAssemblies.Add("Sy
stem.dll");
cplist.ReferencedAssemblies.Add("Sy
stem.XML.dll");
cplist.ReferencedAssemblies.Add("Sy
stem.Web.Services.dll");
cplist.ReferencedAssemblies.Add("Sy
stem.Data.dll");
//编译代理类
CompilerResults cr = icc.CompileAssemblyFromDom(cplist,'courier new'; font-size:14px; line-height:21px">
if (true == cr.Errors.HasErrors)
{
Sy
stem.Text.StringBuilder sb = new Sy
stem.Text.StringBuilder();
foreach (Sy
stem.CodeDom.Compiler.CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString());
sb.Append(Sy
stem.Environment.NewLine);
}
throw new Exception(sb.ToString());
}
Sy
stem.Reflection.Assembly assembly = cr.CompiledAssembly;
Type t = assembly.GetType(@namespace + "." + classname,true,true);
object obj = Activator.CreateInstance(t);
//return mi.Invoke(obj,args);//我就是
添加了下面的语句,就算是完全
解决了
调用WebService中
函数带参和不带参的
方法,虽然我对一些理论不是很清楚,但是用拼凑的
方法调试总是
解决了,还是早点把这个程序弄完吧。
if (args[0] != "")
return mi.Invoke(obj,'courier new'; font-size:14px; line-height:21px">
else
//Invoke(obj,BindingFlags.Default,new
mybinder(),new Object[] { (int)32,(int)32 },CultureInfo.CurrentCulture);//这个是msdn上的,比较复杂有时间再琢磨。
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"?>
<appSettings>
<add key="WebService_url" value="http://192.168.3.117/ws/Service.asmx" />
</appSettings>
WebService的
代码:
using Sy
stem.Web.Services.Protocols;
using Sy
stem.Web.UI.WebControls;
using Sy
stem.Web.UI.WebControls.WebParts;
using Sy
stem.Web.UI.HtmlControls;
using Sy
stem.Data.OracleClient;
namespace handsome
[WebService(Namespace = "http://www.xxxx.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
//若要允许使用 ASP.NET AJAX 从脚本中
调用此 Web 服务,请取消对下行的注释。
// [Sy
stem.Web.Script.Services.ScriptService]
public class Service : Sy
stem.Web.Services.WebService
public Service()
//如果使用设计的组件,请取消注释以下行
//InitializeComponent();
private void InitializeComponent()
[WebMethod]
public string HelloWorld1()
myheader.isValid(out msg);
return "Hello World1";
[SoapHeader("myheader")]
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,new string[] { "CZXSFP-1202000088" });
文件下载前端:
http://files.cnblogs.com/handsome1234/DynamicCallWebservice_Demo.rar