Creating and exposing a SOAP service and its WSDL dynamically in C# (with a custom TCP listener!)

前端 未结 3 1475
不知归路
不知归路 2020-12-13 11:42

I\'ve got a custom HTTP server built in C# which accepts requests for REST services and responds with XML or JSON (depending on what the client needs). The REST services are

相关标签:
3条回答
  • 2020-12-13 11:51

    Don't parse SOAP unless you really have to, let WCF do the heavy lifting for you, generate service- and datacontracts in C# code from your definitions and compile at runtime . Generate a service implementation that hooks into your "static" code through a well known interface.

    Dynamically create endpoints with the correct binding for the new service contracts/data contracts. If bindings don't change dynamically this could be defined in you app.config otherwise set this in runtime as well.

    add a Mex endpoint to get the wsdl published.

    For "examining" incoming traffic use a MessageInspector

    self host the WCF/SOAP service in your HTTP server using ServiceHost -> Self Hosting WCF

    Just some ideas on another approach.

    0 讨论(0)
  • 2020-12-13 11:53

    To create a wsdl dynamically you can use ServiceDescriptionReflector

    For example: for class

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

    you can use this code

    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();
    

    But since you've said

    Publishing a WSDL generated at runtime from the method definitions in the database

    you have to create the Type at runtime

    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();
    

    Now you can use type to create 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();
    

    For reading request and forming response, you can use Linq2Xml. Fiddler can give you an idea about SOAP(xml) format sent between client and server

    0 讨论(0)
  • 2020-12-13 12:10

    SOAP is "just" an XML-based protocol for information exchange. Implementing support for it from the ground up would be tedious but not hugely complicated in principle, I don't think.

    The official SOAP specifications can be found here.

    0 讨论(0)
提交回复
热议问题