一.WCF应用程序:
1.接口:
namespace HSRHINIntf.Service
{
[ServiceContract]
public interface IRHINIntf
{
[OperationContract]
string HSTest(string s);
}
}
2.实现:
namespace HSRHINIntf.Service
{
public class RHINIntf : IRHINIntf
{
public string HSTest(string s)
{
return s + "张三";
}
}
}二.exe宿主
1.App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!--添加服务-->
<service name="HSRHINIntf.Service.RHINIntf" behaviorConfiguration="CalculatorServiceBehavior">
<!--name 必须与代码中的host实例初始化的服务一样
behaviorConfiguration 行为配置 -->
<host>
<baseAddresses>
<!--添加调用服务地址-->
<add baseAddress="http://localhost:8000/webservice/RHINIntf"/>
</baseAddresses> </host>
<!--添加契约接口 contract="WcfDemo.IService1" WcfDemo.IService1为契约接口 binding="wsHttpBinding" wsHttpBinding为通过Http调用-->
<endpoint address="" binding="wsHttpBinding" contract="HSRHINIntf.Service.IRHINIntf"></endpoint>
</service> </services>
<!--定义CalculatorServiceBehavior的行为-->
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior> </serviceBehaviors> </behaviors>
</system.serviceModel>
</configuration>
2.启用服务的代码:
ServiceHost host = null;//定义 ServiceHost
private void btnStart_Click(object sender, EventArgs e)
{
//WcfDemo.Service1 为引用的dll中的服务
host = new ServiceHost(typeof(HSRHINIntf.Service.RHINIntf));
host.Open();//启动服务
this.lbStatus.Text = "WCF服务已启动...";
}三.客户端调用private void button1_Click(object sender, EventArgs e)
{
//定义参数
string[] args = new string[1];
args[0] = ""; //调用接口
object o = InvokeWebService("http://localhost:8000/webservice/RHINIntf?wsdl", "RHINIntf", "HSTest", args); MessageBox.Show(o.ToString());
}//调用函数,返回函数执行结果
public static object InvokeWebService(string url, string classname, string methodname, object[] args)
{
string @namespace = "HSRHINIntf.Service";
//获取Web Service描述
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url); //这里指定你自己的web service url,一定要以?WSDL结尾
ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
sdi.ProtocolName = "soap";
sdi.Style = ServiceDescriptionImportStyle.Client;
sdi.AddServiceDescription(sd, null, null);
//指定命名空间
CodeNamespace cn = new CodeNamespace(@namespace); //这里随便指定一个命名空间,但要与后面的一致
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);
//建立C#编译器
CSharpCodeProvider csc = new CSharpCodeProvider();
ICodeCompiler icc = csc.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
//添加编译条件
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.XML.dll");
cp.ReferencedAssemblies.Add("System.Web.Services.dll");
cp.ReferencedAssemblies.Add("System.Data.dll"); //编译程序集
CompilerResults cr = icc.CompileAssemblyFromDom(cp, ccu);
//检查是否编译成功
if (!cr.Errors.HasErrors)
{
//编译成功
//获取程序集
Assembly assembly = cr.CompiledAssembly;
//获取程序集类型
//前面的Test就是命名空间,必须要与前面指定的一致
//后面的TestService就是service的类名
//如果所有的服务器都是一致的类名,这里就可以写死,否则要动态提供类名
Type type = assembly.GetType(@namespace + "." + classname, true);
object service = Activator.CreateInstance(type);
//获取方法
//如果所有的服务器都是一致的方法名,这里可以写死,否则就要动态提供方法名
MethodInfo mi = type.GetMethod(methodname);
//调用方法
//如果方法没有参数,第二个参数可以传递null,否则就要传递object数组,数组元素的顺序要与参数的顺序一致
//如果所有服务器的方法签名都是一致的,object数组的顺序就可以写死了,否则还要动态调整元素的数量及顺序
return mi.Invoke(service, args);
//最后,返回的是object类型,根据方法的签名,把返回值转换成不同的对象即可。
}
else
{
return null;
//这里自己处理编译错误
}
}在“Type type = assembly.GetType(@namespace + "." + classname, true);”处提示:未能从程序集“.....”中加载类型"HSRHINIntf.Service.RHINIntf"
1.接口:
namespace HSRHINIntf.Service
{
[ServiceContract]
public interface IRHINIntf
{
[OperationContract]
string HSTest(string s);
}
}
2.实现:
namespace HSRHINIntf.Service
{
public class RHINIntf : IRHINIntf
{
public string HSTest(string s)
{
return s + "张三";
}
}
}二.exe宿主
1.App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!--添加服务-->
<service name="HSRHINIntf.Service.RHINIntf" behaviorConfiguration="CalculatorServiceBehavior">
<!--name 必须与代码中的host实例初始化的服务一样
behaviorConfiguration 行为配置 -->
<host>
<baseAddresses>
<!--添加调用服务地址-->
<add baseAddress="http://localhost:8000/webservice/RHINIntf"/>
</baseAddresses> </host>
<!--添加契约接口 contract="WcfDemo.IService1" WcfDemo.IService1为契约接口 binding="wsHttpBinding" wsHttpBinding为通过Http调用-->
<endpoint address="" binding="wsHttpBinding" contract="HSRHINIntf.Service.IRHINIntf"></endpoint>
</service> </services>
<!--定义CalculatorServiceBehavior的行为-->
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior> </serviceBehaviors> </behaviors>
</system.serviceModel>
</configuration>
2.启用服务的代码:
ServiceHost host = null;//定义 ServiceHost
private void btnStart_Click(object sender, EventArgs e)
{
//WcfDemo.Service1 为引用的dll中的服务
host = new ServiceHost(typeof(HSRHINIntf.Service.RHINIntf));
host.Open();//启动服务
this.lbStatus.Text = "WCF服务已启动...";
}三.客户端调用private void button1_Click(object sender, EventArgs e)
{
//定义参数
string[] args = new string[1];
args[0] = ""; //调用接口
object o = InvokeWebService("http://localhost:8000/webservice/RHINIntf?wsdl", "RHINIntf", "HSTest", args); MessageBox.Show(o.ToString());
}//调用函数,返回函数执行结果
public static object InvokeWebService(string url, string classname, string methodname, object[] args)
{
string @namespace = "HSRHINIntf.Service";
//获取Web Service描述
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url); //这里指定你自己的web service url,一定要以?WSDL结尾
ServiceDescription sd = ServiceDescription.Read(stream); ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
sdi.ProtocolName = "soap";
sdi.Style = ServiceDescriptionImportStyle.Client;
sdi.AddServiceDescription(sd, null, null);
//指定命名空间
CodeNamespace cn = new CodeNamespace(@namespace); //这里随便指定一个命名空间,但要与后面的一致
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);
//建立C#编译器
CSharpCodeProvider csc = new CSharpCodeProvider();
ICodeCompiler icc = csc.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
//添加编译条件
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("System.XML.dll");
cp.ReferencedAssemblies.Add("System.Web.Services.dll");
cp.ReferencedAssemblies.Add("System.Data.dll"); //编译程序集
CompilerResults cr = icc.CompileAssemblyFromDom(cp, ccu);
//检查是否编译成功
if (!cr.Errors.HasErrors)
{
//编译成功
//获取程序集
Assembly assembly = cr.CompiledAssembly;
//获取程序集类型
//前面的Test就是命名空间,必须要与前面指定的一致
//后面的TestService就是service的类名
//如果所有的服务器都是一致的类名,这里就可以写死,否则要动态提供类名
Type type = assembly.GetType(@namespace + "." + classname, true);
object service = Activator.CreateInstance(type);
//获取方法
//如果所有的服务器都是一致的方法名,这里可以写死,否则就要动态提供方法名
MethodInfo mi = type.GetMethod(methodname);
//调用方法
//如果方法没有参数,第二个参数可以传递null,否则就要传递object数组,数组元素的顺序要与参数的顺序一致
//如果所有服务器的方法签名都是一致的,object数组的顺序就可以写死了,否则还要动态调整元素的数量及顺序
return mi.Invoke(service, args);
//最后,返回的是object类型,根据方法的签名,把返回值转换成不同的对象即可。
}
else
{
return null;
//这里自己处理编译错误
}
}在“Type type = assembly.GetType(@namespace + "." + classname, true);”处提示:未能从程序集“.....”中加载类型"HSRHINIntf.Service.RHINIntf"
我就是想通过这个URL动态访问webservice中的HSTest函数。