繁体   English   中英

动态C#.NET Web服务

[英]Dynamic C#.NET Webservice

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

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

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

您可以使用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;
   }
}

创建一个继承自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作为您自己的文档处理程序的起点。 请参阅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中,您应该能够使用通配符映射的通用处理程序执行类似的操作。

这是一个建议:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM