\


 Monday, 13 September 2004
Http modul pro změnu URL adresy ve WSDL webové služby

Webové služby v ASP.NET generují dynamické WSDL, ve kterém je adresa služby (obsah elementu soap:address) dynamicky určena podle url původního požadavku. Například při použití reverzní proxy by se hodilo určit adresu ve wsdl dokumentu staticky a přitom stále ponechat na ASP.NET generování většiny elementů ve wsdl dokumentu.

K tomuto účelu jsem napsal http modul pro změnu adresy. V kódu se předpokládá, že nové url webové služby je zadáno ve web.config v sekci appSettings pod klíčem newUrl a že k službě je přistupováno pouze přes protokol SOAP.

using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Diagnostics;
namespace RSTEIN.HttpModules
{
    /// 
    /// Modul pro změnu
    /// 
    public class ChangeUrlModule : IHttpModule
    {
        
        #region private constants                
        private const string WSDL_REQUEST = "wsdl";
        private const string SOAP_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/soap/";
        private const string SOAP_PREFIX = "soap";
        private const string LOCATION_NAME = "location";
        private const string ADDRESS_NAME = "address";
        #endregion private constants                
        #region private variables
        private readonly string m_newServiceUrl;
        #endregion private variables
        #region Constructors
        /// 
        /// Konstruktor
        /// 
        public ChangeUrlModule()
        {
            m_newServiceUrl = System.Configuration.ConfigurationSettings.AppSettings["newUrl"];
        }
    #endregion Constructors
    
    #region IHttpModule Members
        /// 
        /// Inicializace modulu - Součást rozhraní 
        /// 
        /// 
        public void Init(HttpApplication context)
        {
            if (m_newServiceUrl != String.Empty)
            {
                context.BeginRequest +=new EventHandler(context_BeginRequest);
                context.EndRequest +=new EventHandler(context_EndRequest);
            }
        }
        /// 
        /// Součást rozhraní 
        /// 
        public void Dispose()
        {
        }
        #endregion
        
        #region private methods
        //Zapsání jiného URL
        private void context_EndRequest(object sender, EventArgs e)
        {
            string path = HttpContext.Current.Request.RawUrl.ToLower();
            if (isWSDLRequest())
                changeUrl();
        }
        
        //Změna Url www služby
        private void changeUrl()
        {
            HttpResponse response = HttpContext.Current.Response;
            XmlDocument doc = new XmlDocument();
            MemoryStream originalStream = ((FilterStream)response.Filter).InnerStream;
            originalStream .Position = 0;
            try
            {
                
                XmlTextReader reader = new XmlTextReader(originalStream);
                doc.Load(reader);
            }
            catch (Exception e)
            {
                Trace.WriteLine("Invalid response");
                return;
            }
            
            XmlNamespaceManager namManager = new XmlNamespaceManager(doc.NameTable);
            namManager.AddNamespace(SOAP_PREFIX, SOAP_NAMESPACE);
            XmlNode locationNode = getLocationAttribute(doc);
            locationNode.Value = m_newServiceUrl;
            response.Clear();
            doc.Save(response.Output);
            
        }
        //Vyhledání atributu location elementu soap:address
        private XmlNode getLocationAttribute(XmlDocument doc)
        {
            XmlNode addressNode = doc.GetElementsByTagName(ADDRESS_NAME, SOAP_NAMESPACE)[0];
            return addressNode.Attributes["location"];
        }
        #endregion private methods
        //přiřazení filtru na objekt Response
        private void context_BeginRequest(object sender, EventArgs e)
        {
            if (isWSDLRequest())
                HttpContext.Current.Response.Filter = new FilterStream(HttpContext.Current.Response.Filter);
        }
        //Kontrola, zda se jedná o WSDL požadavek
        private bool isWSDLRequest()
        {
            string path = HttpContext.Current.Request.RawUrl.ToLower();
            if (path.EndsWith(WSDL_REQUEST))
                return true;
            return false;
        }
    }
}


O významu http modulů a jejich registraci ve web.config se více dočtete v mém starším článku na Interval.cz.



Monday, 13 September 2004 15:12:00 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Web Services