Sirviendo gráficos SVG dinámicamente

miércoles, 3 de diciembre de 2008

Para mostrar imagenes SVG dentro de un html disponemos del tag embed, el cual funciona en los dos navegadores mas usados actualmente, IE6/7 y Firefox3.

Pero ¿Que pasa si las imagenes no estan en el sistema de ficheros de nuestra web? Lo mas normal es disponer de un servicio que nos devuelva la imagen, que para este caso son imagenes SVG.

Este servicio puede ser tranquilamente una página aspx o un handler ashx(http://miservidor/miaplicacion/miservicio.ashx?imagen=1) que nos devuelva el fichero utilizando el siguiente código:

Response.ContentType = "image/svg+xml";
Response.AddHeader("content-disposition",
"inline; filename=imagen.svg");
Response.Write(contenido_svg);
Response.Flush();


En el elemento embed del html la inclusion sería algo así como:
<embed 
src="http://miservidor/miaplicacion/miservicio.ashx?imagen=1"
type="image/svg+xml"
width="300" height="100"
pluginspage="http://www.adobe.com/svg/viewer/install/" />


Pues bien, resulta que eso si funciona correctamente en firefox, ya que parece que hace caso al content-type, pero para no variar en el IE NO FUNCIONA!!!

Lo único que reconoce y pinta adecuadamente son los ficheros con extensión SVG, asi que no hay mas remedio que crear un manejador de peticiones que controle en nuestra aplicación web todas las peticiones con esta extensión y modificar el atributo src de nuestro embed.
<embed 
src="http://miservidor/miaplicacion/miservicio.svg?imagen=1"
type="image/svg+xml"
width="300" height="100"
pluginspage="http://www.adobe.com/svg/viewer/install/" />


Ahora lo que nos queda es especificar a nuestra aplicación web que todas las peticiones SVG pasen por nuestro código en lugar de buscarlos en su sistema de ficheros; y para hacer esto debemos hacer dos pasos:
  1. Crear una clase que implemente de IHttpHandler en el App_Code
  2. Mapear en el web.config todas las peticiones SVG para que las redirija a nuestra clase.

Creación de la clase que implementa IHttpHandler
public class SVGHandler : IHttpHandler{

public void ProcessRequest(HttpContext context){
HttpRequest Request = context.Request;
string imagen = Request.QueryString["imagen"]; //id de la imagen a mostrar
string contenido_svg = MiServicio.ObtenerContenidoImagen(imagen);
HttpResponse Response = context.Response;
Response.ContentType = "image/svg+xml";
Response.AddHeader("content-disposition", "inline; filename=imagen.svg");
Response.Write(contenido_svg);
Response.Flush();

}

public bool IsReusable{ get{return false;} }
}


Mapeo de la extensión svg en el web.config
<httpHandlers>
...
<add verb="*" path="*.svg" type="SVGHandler"/>
...
</httpHandlers>


Y listo!!! ya podemos incrustar imagenes SVG de contenido dinámico, sin tener problemas de compatibilidad entre IE y Firefox.
<embed 
src="http://miservidor/miaplicacion/miservicio.svg?imagen=1"
type="image/svg+xml"
width="300" height="100"
pluginspage="http://www.adobe.com/svg/viewer/install/" />


Finalmente hay que recordar que la extensión SVG la tenemos que tener registrada dentro del IIS para que este acepte las peticiones con esta extensión.

Enlaces relacionados :

- FIN -