我在C#ASP.NET项目中使用一个类,允许用一些随机脚本语言编写的脚本动态公开webservice方法 - 换句话说,脚本应该能够公开任何带有任何签名的任何名称的方法(只要它是有效的,无论如何)通过这个SOAP接口到外部世界(能够随意添加和删除它们,而无需更改硬代码),因此我需要能够在C#中创建一个web服务类同时能够在运行时动态添加和删除方法。
现在,我能够提出的最好的计划是(运行时)生成C#代码来表示webservice,使用System.Reflection.Emit编译它然后在运行时加载程序集 - 所有这一切脚本在服务中添加或删除方法(不应经常发生,请注意)。
有没有人有比这更好的想法?
答案 0 :(得分:5)
您可以使用SoapExtensionReflector类修改WSDL。来自Kirk Evans Blog:
在反映类型时调用SoapExtensionReflector以提供服务的WSDL定义。您可以利用此类型拦截反射调用并修改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);
}
}
}
}
将此添加到web.config中的configuration / system.web部分:
<webServices>
<soapExtensionReflectorTypes>
<add type="TestWebservice.MyReflector, TestWebservice" />
</soapExtensionReflectorTypes>
</webServices>
这应该为您提供从WSDL文档动态删除方法的起点。如果禁用,则还需要从Web方法中抛出NotImplementedException。
最后,您需要禁用通过调用.asmx端点而不使用?WSDL参数生成的Web服务文档。将wsdlHelpGenerator元素的href属性设置为某个URL。您可以使用DefaultWsdlHelpGenerator.aspx作为您自己的文档处理程序的起点。请参阅XML Files, August 2002中的有关Web服务文档的问题。
答案 1 :(得分:2)
XMLRPC已经死了,不是吗?
SOAP意味着WSDL。如何动态生成WSDL?
您应该考虑使用WCF。我希望您能够控制生成WSDL(和其他元数据)的过程,但您还应该能够控制传入消息的处理。特别是,您将能够检查传入的消息,以确定要运行的脚本,要传递的参数等。
答案 2 :(得分:2)
您可以创建输入和输出类型为xs:any
的WCF服务,并将传入请求作为原始Message
处理。这将允许您接受任何类型的数据并返回任何类型的数据。您不会使用数据合同或静态类型,只需Message
和Message
。
这种方法的问题在于,除了提供一个包装器来调用方法之外,从WSDL生成代理实际上没有帮助消费者。提供方法可接受的数据将需要手动滚动数据类型等,这并不难,它不像硬类型合同那样直观。
答案 3 :(得分:1)
它必须是SOAP接口吗?听起来它可能更适合基于路由/ REST / etc的API。您可以在ASP.NET MVC中执行某些操作(使用自定义IController.Execute
方法来解析对该方法的操作)非常容易(事实上,我正在为some of my own code目前正在处理非常类似的事情)。
例如,您可能有路线:
http://myserver/myservice/mymethod
接受(在body或args中)有效负载(参数),并在响应中返回结果。在非MVC中,您应该能够使用通配符映射的通用处理程序执行类似的操作。
答案 4 :(得分:0)
这是一个建议:
使用WCF从WCF创建WSDL 以下博客中的信息 交:
http://www.pluralsight.com/community/blogs/kirillg/archive/2006/06/18/28380.aspx
然后您可以发布此信息 使用MEX。
然后,您的服务将开放 客户端下载元数据 并致电服务。