动态C#.NET Web服务

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

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

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

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

当您的类型被reflection以提供服务的WSDL定义时,将调用SoapExtensionReflector。 您可以利用此类型拦截reflection调用并修改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; } } 

创建一个inheritance自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); } } } } 

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

      

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

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

XMLRPC已经死了,不是吗?

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

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

您可以使用输入和输出类型xs:any创建WCF服务,并将传入请求作为原始Message 。 这将允许您接受任何类型的数据并返回任何类型的数据。 您不会使用数据协定或静态类型,只是Message输入和Message输出。

这种方法的问题在于,除了提供一个包装器来调用方法之外,从WSDL生成代理实际上没有帮助消费者。 提供该方法可接受的数据将需要手动滚动数据类型等,这并不困难,它不像硬类型合同那样直观。

它必须是SOAP接口吗? 听起来它可能更适合基于路由/ REST / etc的API。 您可以在ASP.NET MVC中执行某些操作(使用自定义IController.Execute方法来解析对该方法的操作)非常容易(事实上,我正在处理一些非常类似于我自己的代码的东西)。

例如,您可能有路线:

 http://myserver/myservice/mymethod 

接受(在body或args中)有效负载(参数),并在响应中返回结果。 在非MVC中,您应该能够使用通配符映射的通用处理程序执行类似的操作。

这是一个建议: