c# - 动态 C#.NET Web 服务

标签 c# asp.net web-services dynamic reflection.emit

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

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

还有比这更好的主意吗?

最佳答案

您可以使用 SoapExtensionReflector 修改 WSDL类(class)。来自 Kirk Evans Blog :

The SoapExtensionReflector is called when your type is being reflected over to provide the WSDL definition for your service. You can leverage this type to intercept the reflection call and modify the WSDL output.

以下示例从 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。

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

关于c# - 动态 C#.NET Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/930753/

相关文章:

c# - 将字符串转换为函数

asp.net - MSAL 3.x GetAuthorizationRequestUrlParameterBuilder 返回错误的数据类型

asp.net - 从 ASP.NET 网站编译代码

java - CXF JAXRS - 如何 POST 多个参数

jquery - 随 jQuery Ajax 请求一起发送 cookie

c# - 从 JavaScript 访问 Silverlight 3.0 应用程序

c# - 将 Shapes.Path 项目绑定(bind)到 ItemsControl

java - 在同一场 war 中从另一个 Web 服务调用 Web 服务 - apache cxf

c# - 处理 IConnectableObservable 不会发送 OnComplete

javascript - 在 ajax 调用之前调用 return 语句