动态C#.NET Webservice [英] Dynamic C#.NET Webservice

查看:294
本文介绍了动态C#.NET Webservice的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#ASP.NET项目中使用一个类来允许用一些随机脚本语言编写的脚本来动态地公开webservice方法 - 换句话说,脚本应该能够公开任何名字的方法(只要它有效,无论如何)通过这个SOAP接口到外部世界(能够随意添加和删除它们,而不需要硬代码更改),因此我需要能够在C#中创建一个webservice类同时能够在运行时动态添加和删除方法。



现在,到目前为止我所能想到的最好的方案是(运行时)生成C#代码代表Web服务,使用System.Reflection.Emit编译它,然后在运行时加载程序集 - 只要脚本向服务添加或删除方法(不应该经常出现)。



有人比这更好吗?

解决方案

您可以修改WSDL USI SoapExtensionReflector 类。从 Kirk Evans博客


当您的类型被反映为为您的服务提供WSDL定义时,将调用SoapExtensionReflector。您可以利用此类型拦截反射调用并修改WSDL输出。


以下示例从第2个网络中删除第一个方法服务方式:

  [WebService(Namespace =http://tempuri.org/)] 
[WebServiceBinding (ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1:System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
returnHello World;
}

[WebMethod]
public int Multiply(int a,int b)
{
return a * b;
}
}

创建一个继承自SoapExtensionReflector的类:

 命名空间TestWebservice 
{
public class MyReflector:SoapExtensionReflector
{
public override void ReflectMethod )
{
// no-op
}

public override void ReflectDescription()
{
ServiceDescription description = ReflectionContext.ServiceDescription;
if(description.PortTypes [0] .Operations.Count == 2)
description.PortTypes [0] .Operations.RemoveAt(0);
if(description.Messages.Count == 4)
{
description.Messages.RemoveAt(0);
description.Messages.RemoveAt(0);
}
foreach(在binding.Bindings中绑定绑定)
{
if(binding.Operations.Count == 2)
binding.Operations.RemoveAt(0) ;
}
if(description.Types.Schemas [0] .Items.Count == 4)
{
description.Types.Schemas [0] .Items.RemoveAt(0 );
description.Types.Schemas [0] .Items.RemoveAt(0);
}
}
}
}

添加这到web.config中的配置/ system.web部分:

 < webServices> 
< soapExtensionReflectorTypes>
< add type =TestWebservice.MyReflector,TestWebservice/>
< / soapExtensionReflectorTypes>
< / webServices>

这应该为您提供从WSDL文档动态删除方法的起点。如果禁用,您还需要从Web方法中抛出NotImplementedException。



最后,您需要禁用通过调用.asmx端点而不使用WSDL参数生成的Web服务文档。将wsdlHelpGenerator元素的href属性设置为某个URL。您可以使用DefaultWsdlHelpGenerator.aspx作为您自己的文档处理程序的起点。有关Web服务文档的问题,请参阅 XML文件,2002年8月


I am using a class in a C# ASP.NET project to allow a script written in some random scripting language to expose webservice methods dynamically - in other words, the script should be able to expose a method of any name with any signature (as long as it's valid, anyway) to the outside world through this SOAP interface (able to add and remove them at will, without needing a hard code change), and as such I need to be able to create a webservice class in C# while being able to dynamically add and remove methods at runtime.

Now, the best plan I've been able to come up with so far is (runtime) generating C# code to represent the webservice, using System.Reflection.Emit to compile it and then loading the assembly at runtime - all whenever the script adds or removes a method to/from the service (should not happen very often, mind).

Does anyone have a better idea than this?

解决方案

You can modify WSDL by using SoapExtensionReflector class. From Kirk Evans Blog:

The SoapExtensionReflector is called when your type is being reflected over to provide the WSDL definition for your service. You can leverage this type to intercept the reflection call and modify the WSDL output.

The following example removes the first method out of 2 web service methods:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
   [WebMethod]
   public string HelloWorld()
   {
      return "Hello World";
   }

   [WebMethod]
   public int Multiply(int a, int b)
   {
      return a * b;
   }
}

Create a class inherited from SoapExtensionReflector:

namespace TestWebservice
{
   public class MyReflector : SoapExtensionReflector
   {
      public override void ReflectMethod()
      {
         //no-op
      }

      public override void ReflectDescription()
      {
         ServiceDescription description = ReflectionContext.ServiceDescription;
         if (description.PortTypes[0].Operations.Count == 2)
            description.PortTypes[0].Operations.RemoveAt(0);
         if (description.Messages.Count == 4)
         {
            description.Messages.RemoveAt(0);
            description.Messages.RemoveAt(0);
         }
         foreach (Binding binding in description.Bindings)
         {
            if (binding.Operations.Count == 2)
               binding.Operations.RemoveAt(0);
         }
         if (description.Types.Schemas[0].Items.Count == 4)
         {
            description.Types.Schemas[0].Items.RemoveAt(0);
            description.Types.Schemas[0].Items.RemoveAt(0);
         }
      }
   }
}

Add this to configuration/system.web section in web.config:

<webServices>
   <soapExtensionReflectorTypes>
      <add type="TestWebservice.MyReflector, TestWebservice" />
   </soapExtensionReflectorTypes>
</webServices>

This should give you a starting point to dynamically removing methods from WSDL document. You would also need to throw NotImplementedException from web method if it is disabled.

Finally, you need to disable web service documentation produced by invoking .asmx endpoint without ?WSDL parameter. Set href attribute of wsdlHelpGenerator element to some URL. You can use DefaultWsdlHelpGenerator.aspx as a starting point for your own documentation handler. See question on web service documentation in XML Files, August 2002.

这篇关于动态C#.NET Webservice的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆