Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
domingo, 20 de julio de 2008
ASP.NETEl hecho de que las acciones de los controladores de ASP.NET MVC retornen ActionResults abre un gran abanico de posibilidades para los desarrolladores de sistemas web.

Ya comenté en otra ocasión los distintos subtipos de ActionResult incluidos en el framework, y la posibilidad de crear nuevos descendientes. También tratamos en otro post el retorno de JSON desde los controladores como una potente vía de devolución de datos estructurados a la capa cliente, tras una llamada Ajax.

En esta ocasión vamos a profundizar un poco más, creando nuestro propia subclase de ActionResult para crear acciones con resultados personalizados utilizando la Preview 3 de esta tecnología. Concretamente, crearemos la clase ImageResult, que permitirá a las acciones retornar imágenes JPEG como la mostrada en la siguiente captura:

Demo de ImageResult

Como se puede observar, aparece una imagen con la hora actual sobre un fondo degradado, que es generada en tiempo real desde el servidor al producirse una petición desde la vista mediante un tag <img> estándar:

<h3>La hora es:</h3>
<img src='<%= Url.Action("GetImage") %>' />
 
La llamada al método Url.Action("GetImage") retorna una cadena con la dirección URL de la acción indicada en el parámetro, en este caso GetImage(). De esta forma, cuando el navegador necesite cargar la imagen para mostrarla, realizará una llamada a dicha acción, cuyo código aparece en el controlador de la siguiente forma:
  public ImageResult GetImage()
{
return new ImageResult
{
Width = 400,
Height = 100,
Text = DateTime.Now.ToLongTimeString()
};
}
 
Lo único que hace es retornar un objeto ImageResult inicializado con el ancho y alto deseado, y el texto a escribir. Fijaos en el uso del inicializador de objetos.

Veamos por último con la clase ImageResult:
  public class ImageResult: ViewResult
{
public int Width { get; set; }
public int Height { get; set; }
public string Text { get; set; }

public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = "image/jpeg";

Rectangle rect = new Rectangle(0, 0, Width, Height);
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
Graphics g = Graphics.FromImage(bmp);
Font font = new Font("Arial", Height / 1.6f);
LinearGradientBrush brush =
new LinearGradientBrush(rect, Color.Blue, Color.Navy, 90f);

g.FillRectangle(brush, rect); // Pinta el degradado...
g.DrawString(Text, font, Brushes.Black, 2, 2); // ... la sombra del texto...
g.DrawString(Text, font, Brushes.White, 0, 0); // ... y el texto.

g.Dispose();
font.Dispose();
brush.Dispose();

bmp.Save(context.HttpContext.Response.OutputStream, ImageFormat.Jpeg);
bmp.Dispose();
}
}
 
Aparte de la definición de las propiedades necesarias para su funcionamiento, el único truco a la hora de devolver contenidos personalizados es sobrescribir el método ExecuteResult de la clase base ViewResult. Ya en su implementación, a través del contexto que nos llega como parámetro podemos modificar el tipo de contenidos de la respuesta (Content-Type) y escribir a través del canal de salida lo que deseemos (en este caso utilizamos el método Save del bitmap para ello).

El resto del código no tiene demasiado interés, es la creación de la imagen dinámica utilizando GDI+. Por cierto, no he realizado validaciones de las propiedades, os los dejo de deberes ;-); Tampoco sé si tantos Dispose() explícitos serán necesarios, supongo que no, pero me da algo de repelús no ponerlos... debe ser algo así como un trauma infantil adquirido años atrás usando el API de Windows...

Proyecto para ASP.NET MVC CTP3 Descargar proyecto (Visual Web Developer 2008 + SP1 + ASP.NET MVC Preview 3).

Publicado en: www.variablenotfound.com.

1 comentario:

Anónimo dijo...

Gracias