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)
Web Services