Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
511 views
in Technique[技术] by (71.8m points)

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

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 defined at runtime from a database-based configuration, vary widely in input parameters and output types, and it's working beautifully in production.

However, I'd like to add SOAP access to the same services, with appropriate WSDLs as well. Since the available services aren't hard-coded, this means:

  • Publishing a WSDL generated at runtime from the method definitions in the database
  • Parsing incoming SOAP requests, mapping them to those definitions, and making sure the requests conform to the method signature before handling them
  • Once the response is handled, creating a SOAP response meeting the WDSL to return the results

The MS documentation (and Google) documents using Visual Studio to generate web services (and WSDLs) at design time, exposing stuff using WebMethods, ASP.NET MVC etc. This isn't what I'm looking for, as there are no method definitions from which to generate the bindings at design time.

Does anyone have any ideas (e.g. toolkits for raw SOAP parsing), and thoughts on generation of WSDLs from dynamically created method signatures, etc? Any idea how one might go about building such things if not? I'm looking to avoid re-inventing the wheel if possible.

PS: Clearly there's standardised stuff in the .NET framework for this, since Visual Studio does it for you - any ideas how to access that at a lower level, at runtime?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...