Usuario
Guardar Imágenes en Sql server con C# en 3 capas

Pregunta
-
Necesito ayuda en como insertar datos y entre ellos imágenes en un proyecto estructurado en 3 capas, su estructura la tengo de esta forma:
NE LA CAPA DE NEGOCIACIÓN:
class NegImagenes_Escaneadas
{
#region Declaracion de Variables
private int Id_Imagen;
private string TipoActa;
private Image Imagen;
private string Descripcion;
#endregion
#region Métodos Get y Set
public int _Id_Imagen
{
get { return Id_Imagen; }
set { Id_Imagen = value; }
}
public string _TipoActa
{
get { return TipoActa; }
set { TipoActa = value; }
}
public Image _Imagen
{
get { return Imagen; }
set { Imagen = value; }
}
public string _Descripcion
{
get { return Descripcion; }
set { Descripcion = value; }
}
#endregion
#region Insertar
public bool Insertar(string TipoActa, Image Imagen, string descripcion)
{
dtImagenes_Escaneadas img = new dtImagenes_Escaneadas();
_TipoActa = TipoActa;
_Imagen = Imagen;
_Descripcion = descripcion;
return img.agregar(this);
}
#endregionEN CONEXION Y ACCESO A DATOS:
class Conexion
{
//CADENA DE CONEXIÓN PARA BASE DE DATOS LOCAL DEL VISUAL
//private static string cadenaconexion = ConfigurationManager.ConnectionStrings["AlcaldiaConnectionString"].ConnectionString;
//CADENA DE CONEXIÓN PARA BASE DE DATOS LOCAL DE SQL SERVER
private static string cadenaconexion = "Data Source=DESKTOP-TB9QPQN\\SQLEXPRESS;Initial Catalog=Alcaldia_Inventario;Integrated Security=True";
private static string proveedor = ConfigurationManager.ConnectionStrings["AlcaldiaConnectionString"].ProviderName;
public static string _cadenaconexion
{
get { return cadenaconexion; }
}
public static string _proveedor
{
get { return proveedor; }
}
}ACCESO A DATOS:
class dtImagenes_Escaneadas
{
#region Insertar Datos
public bool agregar(NegImagenes_Escaneadas datos)
{
DbProviderFactory Factory = DbProviderFactories.GetFactory(Conexion._proveedor);
//Configurar paramétros del procedimiento almacenado generico
DbParameter pTipo = Factory.CreateParameter();
DbParameter pImg = Factory.CreateParameter();
DbParameter pDescripcion = Factory.CreateParameter();
DbCommand comando = datosgenericos.crearcomando();
comando.CommandText = "InsertarImagenes";
comando.CommandType = CommandType.StoredProcedure;
pTipo.ParameterName = "@TipoActa";
pTipo.Value = datos._TipoActa; ;
pImg.ParameterName = "@Imagen";
pImg.Value = datos._Imagen;
pDescripcion.ParameterName = "@Descripcion";
pDescripcion.Value = datos._Descripcion;
comando.Parameters.Add(pTipo);
comando.Parameters.Add(pImg);
comando.Parameters.Add(pDescripcion);
if (datosgenericos.modificar(comando) > 0)
return true;
else
return false;
}
#endregionpublic static int modificar(DbCommand command)
{
int columnas_afectadas = -1;
try
{
command.Connection.Open();
columnas_afectadas = command.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
command.Connection.Close();
}
return columnas_afectadas;
}EN LA CAPA DE PRESENTACION:
NegImagenes_Escaneadas guarda = new NegImagenes_Escaneadas();
//DialogResult r = new System.Windows.Forms.DialogResult();
//SaveFileDialog Dialogo = new SaveFileDialog();
//Dialogo.InitialDirectory = "C:";
//Dialogo.Filter = "Todos los Archivos de Imagen|*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*gif;*.png";
//r = Dialogo.ShowDialog();
Image Imgn=PBImagen.Image;
string Tipo = CBTipo.Text;
string Desc = txtDescripcion.Text;
if (IdImg == 0)
{
//if (r == System.Windows.Forms.DialogResult.OK)
//{
Imgn = PBImagen.Image;
guarda.Insertar(Tipo, Imgn, Desc);
MessageBox.Show("Imagen Guardada.");
//}
}
else
{
MessageBox.Show("Imagen NO Guardada.");
}
}EL ERROR QUE ME DA COMO RESULTADO, ES EL SIGUIENTE:
Excepción no controlada del tipo 'System.ArgumentException' en WindowsFormsApplication1.exe
Información adicional: No hay ninguna asignación de tipo de objeto System.Drawing.Bitmap a un tipo nativo de un proveedor administrado conocido.AYUDA???
Todas las respuestas
-
Te muestro un ejemplo que usé para tomar una foto a los que se inscribían y se almacenaba en una base de datos sqlserver como matriz de byte.
para facilitar las cosas creé una clase para convertir la imagen en matriz de byte y viceversa. Esta clase la puse en la capa de negocios.
public static class Imagen { public static Image GetFoto(byte[] bytesFoto) { Image returnImage = Ingreso.Properties.Resources.SinFoto; if (bytesFoto.Length > 0) { MemoryStream ms = new MemoryStream(bytesFoto); returnImage = Image.FromStream(ms); } return returnImage; } public static byte[] GetByteFoto(Image imagen) { MemoryStream ms = new MemoryStream(); imagen.Save(ms, ImageFormat.Jpeg); return ms.GetBuffer(); } }
En la siguiente clase se modela un Aspirante, cuya foto deseamos guardar (capa de negocios)
public sealed class BOAspirante { ......... //Algunas propiedades public Int32 Dni { get; set; } public String Apellido { get; set; } public String Nombres { get; set; } private Byte[] foto; public Byte[] Foto { get { return foto; } set { foto = value; } } //Guardar la foto public bool GuardarFoto() { bool rta = false; if (this.dni > -1 && this.NuevaFoto) { rta = DAAspirante.GuardarFoto(this.Foto, this.Dni); this.NuevaFoto = false; } return rta; }
Capa de datos
public static bool GuardarFoto(byte[] foto, int dni) { bool rta = false; using (SqlConnection cn = new SqlConnection("Tu conexion")) { cn.Open(); string sql = "UPDATE Inscripciones SET Foto = @Foto WHERE Dni = @Dni"; SqlCommand cmd = new SqlCommand(sql, cn); cmd.Parameters.AddWithValue("@Foto", foto); cmd.Parameters.AddWithValue("@Dni", dni); rta = (int)cmd.ExecuteNonQuery() > 0; } return rta; }
En la capa de presentación:
//Para mostrar los datos en un form private void cargarControles() { BOAspirante a = Inscripcion.Aspirante; txtDni.Text = a.Dni.ToString(); txtApellido.Text = a.Apellido; txtNombre.Text = a.Nombres; pFoto.Image = Imagen.GetFoto(a.Foto); ........... } // Aqui se pudo haber modificado la foto, así que hay que guardarla otra vez. //Para guardar los datos del form private void btnGuardarModif_Click(object sender, EventArgs e) { if (!validar()) return; aspirante.Apellido=txtApellidoNAsp.Text; aspirante.Nombres=txtNombre.Text; aspirante.Foto = Imagen.GetByteFoto(pFoto.Image); .................................. aspirante.GuardarDatos(); aspirante.GuardarFoto(); }
En la base de datos sqlserver2008, el campo "Foto" es del tipo "varbinary(MAX)"
- Editado AntiWork domingo, 20 de mayo de 2018 6:34
-
Excelente, lo logré creando una clase aparte:
class NegImageHelper
{
public static Image ByteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
return Image.FromStream(ms);
}
public static byte[] ImageToByteArray(Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, ImageFormat.Jpeg);
return ms.ToArray();
}
public static Image ObtenerImagenNoDisponible()
{
Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
Stream file = assembly.GetManifestResourceStream("Helpers.Imagenes.NoDisponible.jpg");
return Image.FromStream(file);
}
}Y DENTRO DEL EVENTO DEL BOTÓN:
if (PBImagen.Image != null && CBTipo.Text != "" && txtDescripcion.Text != "")
{
byte[] Imgn = NegImageHelper.ImageToByteArray(PBImagen.Image);
string Tipo = CBTipo.Text;
string Desc = txtDescripcion.Text;
int lbId = Convert.ToInt32(lbIdent.Text);
if (lbId == 0)
{
if (guarda.Insertar(Tipo, Imgn, Desc))
{
MessageBox.Show("Datos Guardados Satisfactorimente");
Limpiar();
}
else
MessageBox.Show("Datosn no Guardados");
}
else
{
if (guarda.Actualizar(lbId, Tipo, Imgn, Desc))
{
MessageBox.Show("Datos Actualizados Satisfactorimente");
Limpiar();
}
else
MessageBox.Show("Datos no Actualizados");
}
}
else
{
MessageBox.Show("Campos Vacíos...");
}Y LISTO, TODO PERFECTO