CodeBars con ASP.NET MVC

Hace tiempo que quiero pasar todos los artículos que tengo en geeks.ms a esta página, pero pasar tantos articulos de varios años no es nada fácil y por más inri tengo el problema que he perdido la mayoría del material que se encontraba en el anterior server.

Por eso he decidido ir pasando los artículos más vistos y si puedo rehacer los ejemplos para que estén disponibles desde mi nuevo site.

Para empezar he recuperado uno de los artículos más vistos que es como crear una imagen dinámicamente con un Handler para ASP.NET Web forms y mostrar un código de barras con la información que pasa el usuario como parámetros.

Estos artículos los puedes repasar en Geeks: http://geeks.ms/blogs/mrubino/archive/2008/12/04/asp-net-codebars.aspx y en mi site http://mrubino.net/2008/12/asp-net-codebars .

Pero estos ejemplos no sirven para la gente que utiliza ASP.NET MVC porque ya no es necesario los Handlers para tratar las imagen y en su defecto podemos crear un controlador que devuelva directamente la imagen dinámica.

Pero mejor hacer un nuevo ejemplo para ver más claro como funcionaría un controlador que nos devuelva la imagen dinámica.

Como en MVC separamos las responsabilidades pues solo necesitamos:

Vista:

Solo necesitamos una página con una lista para seleccionar la fuente para el código de barras, un textBox para que el usuario pueda introducir el texto para generar en código y finalmente una imagen para mostrar el resultado.
Con Razor quedaría de esta manera:

[sourcecode language=»xml»]
@model CodeBar_MVC.Models.Fuente

@Html.DropDownListFor(Model => Model.Id,
new SelectList(ViewBag.Fuentes, "Id", "Nombre"),
new { id = "ddlFuentes" })
@Html.TextBox("txtFuentes")

<input type="button" id="btnImagen" value="clik" />
<img id="imgCodeBar" alt="codeBar" />
[/sourcecode]

El DropDownList se alimenta de una lista devuelta por el controlador «Fuentes» y con el esquema definido en el modelo Fuente.

Controlador:

Tendremos dos acciones, la principal que cargará la lista con las fuentes y la que sustituirá al anterior Handler y devolverá un array de bytes con File, intenté utilizar la función FileStreamResult pero al generar la imagen en memoria y devolver el Stream me retornaba el error. «cannot access a closed stream».

1. Carga de la lista de fuentes:

[sourcecode language=»csharp»]
public ActionResult Index()
{
ViewBag.Fuentes = CodeBarService.GetDatos();
return View();
}
[/sourcecode]

2. Carga la Imagen dinámica con el código de Barras:

[sourcecode language=»csharp»]
public ActionResult GetCodeBar(string code , string format,
int width, int height, int size)
{
return File(CodeBarService.GenerarCodigo(code, format,
width, height, size), "image/jpg");
}
[/sourcecode]

Modelo:

El modelo es muy sencillito y solo tenemos la entidad Fuente.
[sourcecode language=»csharp»]
public class Fuente
{
[Key]
public string Id { get; set; }
public string Nombre { get; set; }
public string Fichero { get; set; }
}[/sourcecode]

No entraré en como utilizar el patrón MVC, porque eso no es  garantiza de que siempre se realicen las cosas correctamente y yo para este ejemplo he creado un servicio en el modelo que contiene toda la lógica
CodeBarService:
  • GetDatos(): La función que se utiliza el controlador para cargar la lista con las fuentes existentes.
  • CargarFuente(string fuente, int size): Se encarga de buscar la fuente y cargarla para utilizar en la imagen.
  • FormatBarCode(string code): Las fuente CodeBars necesitan un código de escape para identificar cuando empieza y termina el código que el lector tiene que leer. Estas fuentes utilizan * como código de escape, pero cada fuente tiene su propia especificación.
  • GenerarCodigo(string code, string format, int width, int height, int size): donde se crea la imagen en memoria y se le añade el texto con la fuente de código de barras y se retorna en formato de bytes[].

[sourcecode language=»csharp»]
public static byte[] GenerarCodigo(string code, string format,
int width, int height, int size)
{
var resultado = new byte[]{};
width = (width == 0) ? 200 : width;
height = (width == 0) ? 60 : height;
size = (width == 0) ? 60 : size;

if (!string.IsNullOrEmpty(code))
{
using (var stream = new MemoryStream())
{
var bitmap = new Bitmap(width, height);
var grafic = Graphics.FromImage(bitmap);
var fuente = CargarFuente(format, size);
var point = new Point();
var brush = new SolidBrush(Color.Black);

grafic.FillRectangle(new SolidBrush(Color.White), 0, 0, width, height);
grafic.DrawString(FormatBarCode(code.ToUpper()), fuente, brush, point);
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
stream.Seek(0, SeekOrigin.Begin);
resultado = stream.ToArray();
}
}

return resultado;
}
[/sourcecode]

Si recordamos en el controlador devolvemos un File Action y con eso tenemos bastante para cargar la imágen dinámicamente para eso nos ayudaremos con un poco de JavaScropt con JQuery.

[sourcecode language=»javascript»]
$(document).ready(function () {

var img = $("#imgCodeBar");
if (img) img.hide();

$("#btnImagen").click(cargarCodeBar);

function cargarCodeBar() {
var btn = $("#btnImagen");

if (img) {
var code = $("#txtFuentes");
var fonts = $("#ddlFuentes");

if (code && fonts) {

img[0].src = "/home/GetCodeBar?code=" +
code.val() +
"&format=" + fonts.val() +
"&width=400&height=60&size=50";
img.show();
}
}
}
});
[/sourcecode]

Lo que hace este script es:

  1. Ocultar la imagen de inicio  y enlazar el evento clic al botón de una forma no intrusiva.
  2. La función cargarCodeBar : recupera la información del documento, enlaza la imagen al controlador  y la muestra actualizada.

Con esto ya lo tenemos todo.

5 comentarios en “CodeBars con ASP.NET MVC”

  1. Gracias.
    Sólo una sugerencia, para los inexpertos como yo …

    CodeBarService.cs

    var path = «C:\\CodeBarMVC\\Content\\Fuentes»;
    var pfc = new PrivateFontCollection();

    ….

    pfc.AddFontFile(path + @»\» + f);
    //pfc.AddFontFile(System.Configuration.ConfigurationManager.AppSettings.Get(«PATH_FONTS») + @»\» + f);

    Gracias….

  2. hola que tal amigo fijate que me marca un error en esta parte del codigo.

    pfc.AddFontFile(System.Configuration.ConfigurationManager.AppSettings.Get(«PATH_FONTS») + @»\» + f);

  3. Buenas tardes amigo. Mi pregunta es la imagen del codigo de barra se puede generar con el texto del codigo? actualmente solo sale la imagen del codigo de barra sin el texto.

    Quedo atento a los comentarios.

    Saludos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio