动态调用webservice,如何接受out返回值。

让我带你走 2010-05-27 09:59:29
问题是这样的。
客户端不是直接调用webservice,中间还有个代理类,这个类负责动态编译调用,webservice。
客户端代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ShangWu168.Tools;
using ShangWu168.Service.Dynamic;
using System.Data;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace ShangWu168.Web
{
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.InitialList();
}
private void InitialList()
{
int intCurrentPage = RequestClass.GetQueryInt("page", 1);//当前页
int PageSize = RequestClass.GetQueryInt("PageSize", 15);//每页条数
string PageCount = "0";//这个地方想接收webservice返回的out值
string RowsCount = "0";//这个地方想接收webservice返回的out
string strUrl = "http://127.0.0.1:78/Pagination.asmx";
string[] args = new string[10];
args[0] = "web_member";
args[1] = "member_id";
args[2] = "*";
args[3] = "desc";
args[4] = "member_id";
args[5] = intCurrentPage.ToString();
args[6] = PageSize.ToString();
args[7] = "member_id>1";
args[8] = PageCount;
args[9] = RowsCount;
Stopwatch sw = new Stopwatch();
sw.Start();
byte[] zipBuffer = (byte[])WebServiceDynamicInvoke.InvokeWebService(strUrl, "Pagination", "GetDataSetSurrogateZipBytes", args); ;
byte[] buffer = UnZip.Decompress(zipBuffer);
BinaryFormatter bf = new BinaryFormatter();
DataSetSurrogate dss = bf.Deserialize(new MemoryStream(buffer)) as DataSetSurrogate;
DataSet ds = dss.ConvertToDataSet();
GridView1.DataSource = ds.Tables[0].DefaultView;
GridView1.DataBind();
sw.Stop();
}
}
}


代理类代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.CodeDom;
using System.Web.Services.Description;

namespace ShangWu168.Service.Dynamic
{
public class WebServiceDynamicInvoke
{
/// <summary>
/// 动态调用WebService
/// </summary>
/// <param name="url">WebService地址</param>
/// <param name="methodname">方法名(模块名)</param>
/// <param name="args">参数列表</param>
/// <returns>object</returns>
public static object InvokeWebService(string url, string methodname, object[] args)
{
return InvokeWebService(url, null, methodname, args);
}
/// <summary>
/// 动态调用WebService
/// </summary>
/// <param name="url">WebService地址</param>
/// <param name="classname">类名</param>
/// <param name="methodname">方法名(模块名)</param>
/// <param name="args">参数列表</param>
/// <returns>object</returns>
public static object InvokeWebService(string url, string classname, string methodname, object[] args)
{
string @namespace = "ServiceBase.WebService.DynamicWebLoad";
if (classname == null || classname == "")
{
classname = WebServiceDynamicInvoke.GetClassName(url);
}
//获取服务描述语言(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 StringBuilder();
foreach (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的out值
}

/// <summary>
/// 解析url获取类名
/// </summary>
/// <param name="url">url地址</param>
/// <returns>string</returns>
private static string GetClassName(string url)
{
string[] parts = url.Split('/');
string[] pps = parts[parts.Length - 1].Split('.');
return pps[0];
}

}
}


...全文
1229 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
william_ys 2012-10-29
  • 打赏
  • 举报
回复
Hi all,
如果在接口中使用了自定义结构作为参数,该如何做(取得其Type)?
  • 打赏
  • 举报
回复
刚好昨天也碰到这样一个问题,动态调用webservice,然后需要进行分页的方法,但是返回的是一个datatable对象。调试发现

if (types.Length == 0)//如果没有out ,或者ref类型参数
{
method = t.GetMethod(functionName);
}
else
{
method = t.GetMethod(functionName, types);//

}
result = method.Invoke(o, args);
在红色标记处调试进去,整个底层方法的调用并没有问题。但是调式返回到红色标记后即爆“调用的目标发生了异常”。
.webservice中的方法如下[code=C#][WebMethod]
public DataTable GetHospitalByPage(string where, int pageSize, int currentIndex, out int recordCount, out int pageCount)
{
HospitalBll hosBll = new HospitalBll();
return hosBll.GetPageList(pageSize, currentIndex, out recordCount, out pageCount, where);
}[/code
  • 打赏
  • 举报
回复
刚好昨天也碰到这样一个问题,动态调用webservice,然后需要进行分页的方法,但是返回的是一个datatable对象。调试发现

if (types.Length == 0)//如果没有out ,或者ref类型参数
{
method = t.GetMethod(functionName);
}
else
{
method = t.GetMethod(functionName, types);//

}
result = method.Invoke(o, args);
在红色标记处调试进去,整个底层方法的调用并没有问题。但是调式返回到红色标记后即爆“调用的目标发生了异常”。
.webservice中的方法如下
[WebMethod]
public DataTable GetHospitalByPage(string where, int pageSize, int currentIndex, out int recordCount, out int pageCount)
{
HospitalBll hosBll = new HospitalBll();
return hosBll.GetPageList(pageSize, currentIndex, out recordCount, out pageCount, where);
}

请大家帮帮忙!
  • 打赏
  • 举报
回复
正好用到·····
让我带你走 2010-05-27
  • 打赏
  • 举报
回复
谢谢您!
我c#基础不太扎实

客户端那边如何调用传值,接收呢


int PageCount = 0;
int RowsCount = 0";
//这两个是参数

WebServiceDynamicInvoke.InvokeWebService(strUrl, "Pagination", "GetDataSetSurrogateZipBytes", args,这里怎么写);
showlin 2010-05-27
  • 打赏
  • 举报
回复

public static object InvokeWebService(string url, string classname, string methodname, object[] args,params Type[] types)
{
……………………
System.Reflection.MethodInfo mi = null;
if (types.Length == 0)
mi=t.GetMethod(methodname);
else
mi=t.GetMethod(methodname, types);
return mi.Invoke(obj, args);//这里不知道如何接受webservice的out值
}

调用你另外一个贴子中4楼的helloworld方法
string msg;
string result=string.Empty;
object[] args=new object[]{result};
Type[] type=new Type[]{Type.GetType("System.String&")};
msg= WebServiceDynamicInvoke.InvokeWebService("http://localhost:10189/web1/WebService.asmx",null, "HelloWorld", args,type).ToString();
MessageBox.Show(msg);
MessageBox.Show(args[0].ToString());



让我带你走 2010-05-27
  • 打赏
  • 举报
回复
请问showlin,这个代理类具体需要怎么改呢?
showlin 2010-05-27
  • 打赏
  • 举报
回复
代理类的方法改下吧

public static object InvokeWebService(string url, string classname, string methodname, object[] args,param Type[] types)
showlin 2010-05-27
  • 打赏
  • 举报
回复
反射调用带ref或out参数的方法时,需要精确指定type的个数与类型
System.Reflection.MethodInfo mi = t.GetMethod(methodname);


System.Reflection.MethodInfo mi = t.GetMethod(methodname,new Type[]
{
Type.GetType("System.Int32"),
Type.GetType("System.Int32&") //这个是out参数
}
);
让我带你走 2010-05-27
  • 打赏
  • 举报
回复

webservice代码
[code=C#]
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Data;
using System.Data.SqlClient;
using ShangWu168.SQL;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
namespace ShangWu168.Service.Control
{
/// <summary>
/// Service1 的摘要说明
/// </summary>
[WebService(Namespace = "ShangWu168.Service.Control")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class Pagination : System.Web.Services.WebService
{
/// <param name="strTableName">表名</param>
/// <param name="strPrimaryKey">主键</param>
/// <param name="strSelectField">查询字段.</param>
/// <param name="strSortWay">排序方式.</param>
/// <param name="strSortField">排序字段</param>
/// <param name="intCurrentPage">当前页</param>
/// <param name="intPageSize">每页读取条数</param>
/// <param name="strSelectWhere">查询条件</param>
/// <returns>byte[]</returns>
[WebMethod(Description = "调用分页存储过程并返回DataSetSurrogate对象用Binary序列化并ZIP压缩后的字节数组")]
public byte[] GetDataSetSurrogateZipBytes(string strTableName, string strPrimaryKey, string strSelectField, string strSortWay, string strSortField, string intCurrentPage, string intPageSize, string strSelectWhere, out string sumpage, out string sum)
{
SqlParameter[] parameters = {
new SqlParameter("@TableName", SqlDbType.VarChar,50),
new SqlParameter("@PrimaryKey", SqlDbType.VarChar,50),
new SqlParameter("@SelectField", SqlDbType.VarChar,1000),
new SqlParameter("@SortWay", SqlDbType.VarChar,50),
new SqlParameter("@SortField", SqlDbType.VarChar,50),
new SqlParameter("@CurrentPage", SqlDbType.Int,4),
new SqlParameter("@PageNum", SqlDbType.Int,4),
new SqlParameter("@SelectWhere", SqlDbType.VarChar,2000),
new SqlParameter("@SumPage", SqlDbType.Int,4),
new SqlParameter("@sum", SqlDbType.Int,4)
};
parameters[0].Value = strTableName;
parameters[1].Value = strPrimaryKey;
parameters[2].Value = strSelectField;
parameters[3].Value = strSortWay;
parameters[4].Value = strSortField;
parameters[5].Value = intCurrentPage;
parameters[6].Value = intPageSize;
parameters[7].Value = strSelectWhere;
parameters[8].Value = ParameterDirection.Output;
parameters[9].Value = ParameterDirection.Output;
DataSet DS = SQLServer.GetNeedDataSet(CommandType.StoredProcedure, "proc_pagination", parameters);
if (DS != null)
{
sum = parameters[8].Value.ToString();//这里返回output值
sumpage = parameters[9].Value.ToString();//这里返回output值
DataSetSurrogate dss = new DataSetSurrogate(DS);
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, dss);
byte[] buffer = ms.ToArray();
byte[] Zipbuffer = Compress(buffer);
return Zipbuffer;
}
else
{
sum = "0";
sumpage = "0";
return null;
}

}
//压缩压缩后的字节数组
private byte[] Compress(byte[] data)
{
MemoryStream ms = new MemoryStream();
Stream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
zipStream.Write(data, 0, data.Length);
zipStream.Close();
ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, int.Parse(ms.Length.ToString()));
return buffer;
}
}
}


[/code]
让我带你走 2010-05-27
  • 打赏
  • 举报
回复
非常感谢终于理解了!
让我带你走 2010-05-27
  • 打赏
  • 举报
回复
请问showlin

return mi.Invoke(obj, args); //这个地方只能返回两个参数啊,我如何返回那两个out值啊啊

12,162

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 Web Services
社区管理员
  • Web Services社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧