10

我有一个用 C# 构建的自定义 HTTP 服务器,它接受对 REST 服务的请求并以 XML 或 JSON 响应(取决于客户端需要什么)。REST 服务是在运行时从基于数据库的配置中定义的,输入参数和输出类型差异很大,并且在生产环境中运行良好。

但是,我想添加对相同服务的 SOAP 访问,以及适当的 WSDL。由于可用服务不是硬编码的,这意味着:

  • 发布运行时从数据库中的方法定义生成的 WSDL
  • 解析传入的 SOAP 请求,将它们映射到这些定义,并在处理它们之前确保请求符合方法签名
  • 处理响应后,创建符合 WDSL 的 SOAP 响应以返回结果

MS 文档(和 Google)文档使用 Visual Studio 在设计时生成 Web 服务(和 WSDL),使用 WebMethods、ASP.NET MVC 等公开内容。这不是我想要的,因为没有方法在设计时从中生成绑定的定义。

有没有人有任何想法(例如用于原始 SOAP 解析的工具包),以及关于从动态创建的方法签名等生成 WSDL 的想法?知道如果没有的话,如何去建造这样的东西吗?如果可能的话,我希望避免重新发明轮子。

PS:很明显,.NET 框架中有标准化的东西,因为 Visual Studio 为你做了 - 任何想法如何在运行时在较低级别访问它?

4

3 回答 3

6

要动态创建 wsdl,您可以使用ServiceDescriptionReflector

例如:对于类

public class TestWebService
{
    [WebMethod]
    public string Hello(string namex)
    {
        return "Hello " + namex;
    }
}

你可以使用这个代码

StringWriter wr = new StringWriter();
var r = new System.Web.Services.Description.ServiceDescriptionReflector();
r.Reflect(typeof(TestWebService), "http://somewhere.com");
r.ServiceDescriptions[0].Write(wr);
var wsdl = wr.ToString();

但是既然你说了

发布运行时从数据库中的方法定义生成的 WSDL

你必须Type在运行时创建

var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyAsm"), AssemblyBuilderAccess.Run);
var mod = asm.DefineDynamicModule("MyModule");

TypeBuilder typeBuilder = mod.DefineType("TestWebService");

MethodBuilder mb = typeBuilder.DefineMethod("Hello", MethodAttributes.Public, CallingConventions.Standard, typeof(string), new Type[] { typeof(string) });
var cab = new CustomAttributeBuilder( typeof(WebMethodAttribute).GetConstructor(new Type[]{}), new object[]{} );
mb.SetCustomAttribute(cab);
mb.DefineParameter(1, ParameterAttributes.In, "namex");
mb.GetILGenerator().Emit(OpCodes.Ret);

Type type = typeBuilder.CreateType();

现在您可以使用type创建 wsdl

StringWriter wr = new StringWriter();
var r = new System.Web.Services.Description.ServiceDescriptionReflector();
r.Reflect(type, "http://somewhere.com");
r.ServiceDescriptions[0].Write(wr);
var wsdl = wr.ToString();

对于读取请求和形成响应,您可以使用 Linq2Xml。 Fiddler可以让您了解客户端和服务器之间发送的 SOAP(xml) 格式

于 2012-07-25T21:10:38.373 回答
2

SOAP“只是”一种基于 XML 的信息交换协议。从头开始实现对它的支持会很乏味,但原则上并不复杂,我不认为。

官方 SOAP 规范可以在这里找到。

于 2012-07-18T20:26:00.693 回答
2

不要解析 SOAP,除非您真的需要,让 WCF 为您完成繁重的工作,根据您的定义在 C# 代码中生成服务和数据契约并在运行时编译。生成一个服务实现,通过众所周知的接口连接到您的“静态”代码。

为新的服务合同/数据合同动态创建具有正确绑定的端点。如果绑定不动态更改,则可以在您的 app.config 中定义,否则也可以在运行时设置。

添加一个 Mex 端点以发布 wsdl。

对于“检查”传入流量,请使用MessageInspector

使用 ServiceHost -> Self Hosting WCF在 HTTP 服务器中自行托管 WCF/SOAP 服务

只是关于另一种方法的一些想法。

于 2012-07-23T09:56:25.183 回答