动态C#.NET Web服务

Fri*_*z H 7 c# asp.net web-services reflection.emit dynamic

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

现在,到目前为止我能够提出的最好的计划是(运行时)生成C#代码来表示web服务,使用System.Reflection.Emit编译它然后在运行时加载程序集 - 所有这些都是脚本添加的或者从服务中删除一个方法(不应该经常发生,请注意).

有没有人有比这更好的主意?

Pav*_*uva 5

您可以使用SoapExtensionReflector类来修改WSDL .来自Kirk Evans博客:

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

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

[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;
   }
}
Run Code Online (Sandbox Code Playgroud)

创建一个继承自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);
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

将其添加到web.config中的configuration/system.web部分:

<webServices>
   <soapExtensionReflectorTypes>
      <add type="TestWebservice.MyReflector, TestWebservice" />
   </soapExtensionReflectorTypes>
</webServices>
Run Code Online (Sandbox Code Playgroud)

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

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