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

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

还有人有比这更好的主意吗?

有帮助吗?

解决方案

可以通过使用 SoapExtensionReflector <修改WSDL / A>类。从柯克埃文斯博客

  

当被反射在你的类型为您服务提供的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;
   }
}

创建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);
         }
      }
   }
}

此添加到配置/ System.Web程序部分在web.config中:

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

此应该给你一个起点动态地去除从WSDL文档的方法。你还需要从web方法抛出NotImplementedException如果它被禁用。

最后,你需要禁用调用的.asmx端点,而无需?WSDL参数产生的Web服务文档。 wsdlHelpGenerator元素设置href属性一些网址。您可以使用DefaultWsdlHelpGenerator.aspx作为自己的文档处理程序的起点。查看Web服务的文档问题在 XML文件,2002年8月

其他提示

XMLRPC是相当死,不是吗?

SOAP意味着WSDL。你如何动态地生成WSDL?

您应该考虑使用WCF。我希望你将能够把生成WSDL(和其他元数据)的过程的控制,但你也应该能够把收到的邮件的处理的控制。特别是,你将能够检查传入的消息以确定要运行的脚本,传递什么参数,等等。

您可以创建与xs:any的输入和输出类型的WCF服务和处理输入的请求作为原料Message。这将使你接受任何类型的数据并返回任何类型的数据。你不会使用数据合同或静态类型,只是在一个MessageMessage了。

这种方法的问题是,从WSDL生成代理确实没有什么比帮助提供一个包装调用该方法的其他消费者。提供的数据是可接受的方法将需要手卷数据类型,等等,其并不难,它只是不作为硬,输入合同直观。

它必须是一个SOAP接口?这听起来像它可能是更适合的路线/ REST /等基于API。你可以做的ASP.NET MVC的东西(与解析动作的方法定制IController.Execute方法)很容易地(其实,我正在上的一些此刻我自己的代码)的。

例如,你可能有路线:

http://myserver/myservice/mymethod

接受(或者在体内或参数)有效负载(参数),并返回结果的响应。在非MVC你应该能够做一个通配符映射通用处理器类似的东西。

这是一个建议:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top