Imam Ferianto Blogs

sekedar catatan kecil saja

SOAP adalah singkatan untuk “Simple Object Access Protocol is an XML-based Web services access protocol”, maksudnya adalah protokol sederhana untuk mengakses web service menggunakan basis dokument XML untuk format requestnya. Bentuk XML yang digunakan bisa jadi sangat sederhana sampai dengan sangat komplek, sehingga defaultnya SOAP tidak “fault tolerance” atau tidak ada penanganan error kesalahan secara default.

Pada framework Dotnet core sendiri sudah mempunyai tools bawaan yang bernama “dotnet-svcutil” yang dapat digunakan untuk mengenerate interface soapclient dari WSDL file atau url yang difeeding. Tools ini sangat praktis digunakan untuk membuat interface soap, dengan sekali menjalankan tools ini otomatis akan tergenerate C# interface class dan method yang didefinisikan dalam WSDL  (web service definition language).

Dalam implementasinya bisa jadi terjadi masalah pada koneksi https misalnya karena SSL Sever sertificate yang invalid ataupun server yang di deploy tidak mendukung sslbypass karena alasan security dan lainnya. Hal ini kemungkinan disebabkan karena bergantung koneksi pada native socket. Untungnya ada cara lain untuk mengakses webservice soap yaitu menggunakan HttpClient biasa (HttpWebRequest), dimana penanganan SSL ataupun bypass SSL invalid sudah default.

Berikut contoh kode implementasi untuk memangil web service menggunakan httpclient . Kode ini praktis dan handy untuk struktur webservice sederhana, Jika sudah komplex, lebih disarankan menggunakan tools dotnet-svcutil .

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Xml;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Security.Claims;
using System.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.Html;
using Microsoft.Extensions.DependencyInjection;

namespace test.Controllers
{
    [Authorize(Policy = "Authenticated")]
    public class DownloaderController : Controller
    {
        private readonly IHttpContextAccessor _accessor;
        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly IServiceScopeFactory _serviceScopeFactory;

        public DownloaderController(IWebHostEnvironment hostingEnvironment,IHttpContextAccessor accessor, IServiceScopeFactory serviceScopeFactory)
        {
            _hostingEnvironment = hostingEnvironment;
            _accessor = accessor;
            _serviceScopeFactory = serviceScopeFactory;
        }

     
        public IActionResult Index()
        {
           return View();
        }

        
        public async Task<IActionResult> DownloadData(){
            string soapResult="";
            try{
		string endpointurl="http://download.com/soapservice/xyz";
		string soapaction="http://sap.com/xi/WebService/soap1.1";
		string soapuser="";
		string soappassword="";
		string xmlstring=@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:urn=""urn:myurl.com:download"">
<soapenv:Header/>
    <soapenv:Body>
      <urn:mt_download_req>
         <CLIENT>xx</CLIENT>
         <TRX_TYPE>xx</TRX_TYPE>
         <REQUESTID>xx</REQUESTID>
      </urn:mt_download_req>
    </soapenv:Body>
</soapenv:Envelope>";
		XmlDocument soapEnvelopeXml = CreateSoapEnvelope(xmlstring);
                HttpWebRequest webRequest = CreateWebRequest(
                endpointurl,
                soapuser,
                soappassword,
                soapaction);

                if(webRequest!=null){
                    InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
                    
                    IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
                    asyncResult.AsyncWaitHandle.WaitOne();

                    using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
                    {
                        using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
                        {
                            soapResult = rd.ReadToEnd();
                        }      
                    }
                }

            }catch(Exception e){

            }

        }

       
        private static HttpWebRequest CreateWebRequest(string url,string username,string password,string soapaction)
        {
            HttpWebRequest webRequest=null;
            try{
                webRequest = (HttpWebRequest) WebRequest.Create(url);
                if(!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password)){
                    string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
                    webRequest.Headers.Add("Authorization", "Basic " + encoded);
                }
                if(!String.IsNullOrEmpty(soapaction)){
                    webRequest.Headers.Add("SOAPAction", soapaction);
                }
                webRequest.ContentType = "text/xml;charset=\"utf-8\"";
                webRequest.Accept = "text/xml";
                webRequest.Method = "POST";
            }
            catch(Exception e){
            }
            return webRequest;
        }

        private static XmlDocument CreateSoapEnvelope(string xmlstring)
        {
            XmlDocument soapEnvelopeDocument = new XmlDocument();
            soapEnvelopeDocument.LoadXml(xmlstring);
            return soapEnvelopeDocument;
        }

        private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
        {
            using (Stream stream = webRequest.GetRequestStream())
            {
                soapEnvelopeXml.Save(stream);
            }
        }

        
 
    }
}