Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Web API interface (WSDL)

I have get some information about ASP Web API. It is look like good stuff for web services but how to create something like WSDL for my API like WCF service does ? how 3d party component can use my service? Or i need to describe each my method manually ?

like image 670
Arbejdsglæde Avatar asked Feb 29 '12 13:02

Arbejdsglæde


1 Answers

This is a slightly different scenario than what the OP probably intended to ask about, but is a more broad interpretation of "how to create something like WSDL for my API like WCF service does?"

I had a situation where we were not able to expose a WCF service, and the only option was WebAPI. However the party consuming the API only supported SOAP/WSDL and had a predefined WSDL that they required integrator to host and conform to.

Serving the WSDL file

One WebAPI action served the WSDL file, which was just a static WSDL file. This approach does not support querying parts of the WSDL. So the client must use URL request yourdomain.com/SomeRoot/SomeApiPath?wsdl, any query string parameters after that will be ignored and the full WSDL will be served. The parameter [FromUri] string wsdl ensures this action is chosen for the URL with ?wsdl in it but will not have any value in it.

public IHttpActionResult SomeApiPath([FromUri] string wsdl)
    {
        System.IO.FileStream wsdlFileStream = System.IO.File.OpenRead(System.Web.HttpContext.Current.Server.MapPath("~/Content/SomeThing.wsdl"));
        var response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new StreamContent(wsdlFileStream);
        response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/xml");
        return ResponseMessage(response);
    }

This means your API Action methods need to handle and respond to XML SOAP requests.

Handling SOAP request

While WebAPI can bind parameters to XML requests, I opted to have no parameters in my actions and instead I used Request.Content.ReadAsStringAsync() in each action to get the request body (which is the XML SOAP request) and then parsed it using XML to LINQ to get specific values I needed. This saved me from trying to reverse engineer an XML serializable POCO to match the WSDL defined request structure.

Creating the SOAP response

You can use tools such as Svcutil.exe with Visual Studio to generate XML serializable POCO's. Since we aren't using WCF, you won't use the full service contract, but just pull out the C# class POCOs so that you can populate them with data and serialize them to XML to create a response. Creating SOAP envelopes that have all the correct namespace references is extremely challenging though. I hacked around in some places and actually used string concatenation instead of XML serialization. Serialize to an XML string, and return that in a StringContent response:

return ResponseMessage(
       new HttpResponseMessage(HttpStatusCode.OK)
       {
           Content = new StringContent(soapResponseBody, System.Text.Encoding.UTF8, "text/xml")
       });

Note: Even exceptions must be caught and converted to XML as a SOAP Fault inside a SOAP envelope.

All of the above terrible workarounds are evidence that if you absolutely must support SOAP, using anything besides WebAPI is going to be much easier. I love WebAPI, but when you have to integrate with another system that only supports SOAP/WSDL, it is certainly not the tool for the job. I provide the above as a summary of the approach to working around this problem when you have no other option, but recommend using a framework besides WebAPI that has SOAP support. You most certainly will run into problems with the above, and will need to have lots of experience with XML serialization and XML schemas to understand how to get through these problems.

It's also pretty odd/rare for someone to have a predefined WSDL and ask others to implement services that expose that WSDL. In other words, they integrate from their side as a client, and you are the host, but they dictate the structure of the requests. Usually it's the other way around, where someone has a service they expose with a predefined WSDL, and you must implement a client to consume it, which is generally a lot easier.

like image 77
AaronLS Avatar answered Sep 28 '22 06:09

AaronLS