post icon

Desplegar ASP.Net en Apache Tomcat sobre GNU/Linux y SQL Server

Éste probablemente sea uno de los post mas raros que escribiré, todo programador cristiano sabe que ASP.net se despliega oficialmente sobre el servidor web de Microsoft IIS, necesitando necesariamente un servidor Windows. Hoy haremos lo que muchos desean, lo que muchos dicen ser imposible, o lo que muchos solamente quieren experimentar, haremos una mini aplicación escrita en C#.net y ASP.net, que se conecte a un servidor de base de datos SQL Server, desplegandolo sobre Apache Tomcat en GNU/Linux.

Existen mods del proyecto mono para instalar sobre Apache que permiten correr ASP.net sobre él, pero no es precisamente eso lo que usaremos, sino algo más extravagante.

¿Y cómo se supone que haremos esto? La empresa Mainsoft (apoyado por Novell) ofrece un producto que forma parte de una comunidad, con licencia openSource, llamado Grasshopper, que viene a ser un plugin para Visual Studio 2008, también tiene otras versiones para las versiones 2003 y 2005 respectivamente, el cual nos permitirá crear un nuevo tipo de proyectos, prepárate para leer esto y siéntate firmemente que puedes caerte de espalda, Visual C# for Java EE, en síntesis escribes en lenguaje .Net y compilas para Java, el abanico de opciones va desde librerías dll, páginas web, aplicaciones en consolas, hasta web services, todo sobre el framework 2.0 por supuesto.

Lo puedes descargar desde aquí, el sitio mismo que ellos tienen, esta construido sobre ASP.net y desplegado sobre Apache Tomcat. Se puede hacerlo sobre Websphere de IBM también según la documentación, pero en este caso no lo usaremos como servidor web.

Lo primero que debemos hacer para probar esto es crear un base de datos en SQL Server, con una tabla a modo de ejemplo llamada Persona, y dos procedimientos almacenados, uno para insertar datos y otro para seleccionarlos. El script va aquí:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
CREATE DATABASE JEE;
GO
USE [jee]
GO
/****** Object:  Table [dbo].[Persona]    Script Date: 01/11/2010 16:40:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Persona](
	[Codigo] [int] IDENTITY(1,1) NOT NULL,
	[Nombre] [varchar](50) NOT NULL,
	[Apellido] [varchar](50) NOT NULL,
	[DocumentoNro] [varchar](50) NOT NULL,
	[Direccion] [varchar](50) NULL,
	[Telefono] [varchar](50) NULL,
	[Email] [varchar](50) NULL,
 CONSTRAINT [PK_Persona] PRIMARY KEY CLUSTERED
(
	[Codigo] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  StoredProcedure [dbo].[BuscarPersona]    Script Date: 01/11/2010 16:40:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[BuscarPersona]
				@Codigo int
AS
BEGIN
	select
		*
	from
		persona p
	where
		p.Codigo = @Codigo;
END
GO
/****** Object:  StoredProcedure [dbo].[AltaPersona]    Script Date: 01/11/2010 16:40:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[AltaPersona]
				 @Nombre varchar(50)
				,@Apellido varchar(50)
				,@DocumentoNro varchar(50)
				,@Direccion varchar(50)
				,@Telefono varchar(50)
				,@Email varchar(50)
AS
BEGIN
	insert into
		 persona
	values (
		 @Nombre
		,@Apellido
		,@DocumentoNro
		,@Direccion
		,@Telefono
		,@Email
		);
END
GO

Una vez instalado el plugin en nuestra previa instalación del Visual Studio, procedemos a crear un nuevo proyecto así como se ve en la imagen.

Una vez creado el dichoso proyecto, creamos la interfaz que tendrá la web, ahora lo haremos bastante simple, minimalista, sin mucha técnica para esto, ya que lo que quiero lograr es desplegar ASP.net sobre Apache Tomcat y no otra desviar el objetivo :P. El código es el que sigue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DevTroceJEE._Default" %>
 
 
 
 
 
<!--
        .style1
        {
            width: 100%;
            height: 252px;
            margin-bottom: 0px;
        }
        .style2
        {
            width: 301px;
        }
        .style3
        {
            width: 301px;
            height: 111px;
        }
        .style4
        {
            height: 111px;
        }
        .style5
        {
            height: 111px;
            width: 998px;
            text-align: center;
        }
        .style6
        {
            width: 998px;
            text-align: center;
        }
        .style7
        {
            width: 301px;
            height: 172px;
        }
        .style8
        {
            width: 998px;
            height: 172px;
            text-align: center;
        }
        .style9
        {
            height: 172px;
        }
        .style10
        {
            color: #B2DB1D;
            font-weight: bold;
            font-family: "Courier New", Courier, "espacio sencillo";
            font-size: large;
        }
        .style11
        {
            text-align: left;
        }
 
-->
 
 
<form id="form1">
 
<div>
 
<table class="style1">
<tbody>
<tr>
<td class="style3"></td>
<td class="style5">
                    <img style="width: 150px; height: 150px;" src="mi-logo.png" alt="DevTroce" />
 
                    <span class="style10">Destrozando Código!</span></td>
<td class="style4"></td>
</tr>
<tr>
<td class="style7"></td>
<td class="style8">
<table class="style1">
<tbody>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11"></td>
<td style="text-align: left;"></td>
</tr>
<tr>
<td class="style11" colspan="2"></td>
</tr>
<tr>
<td class="style11" colspan="2"></td>
</tr>
</tbody>
</table>
</td>
<td class="style9"></td>
</tr>
<tr>
<td class="style2"></td>
<td class="style6">
                    Ningun derecho reservado por DevTroce.com :P</td>
<td></td>
</tr>
</tbody>
</table>
</div>
 
</form>

En el como verán tenemos 3 botones que programar, el código es el siguiente de toda la página, sabrán ordenarla y armarla en si desean reproducirlo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Data;
 
namespace DevTroceJEE
{
    public partial class _Default : System.Web.UI.Page
    {
        // Declarar objeto de conexion
        System.Data.SqlClient.SqlConnection sqlConn;
        // Declarar objeto de ejecucion de comando
        System.Data.SqlClient.SqlCommand sqlComando;
        // Declarar DataReader para la posterior Lectura
        System.Data.SqlClient.SqlDataReader sqlReader;
        // Declarar Variable para almacenar String de Conexion a la BD
        String ConnString;
 
        private void CrearCadenaDeConexion()
        {
            ConnString = "Data Source=FIREBIRDXP;Initial Catalog=JEE;User ID=sa;Password=winner;";
        } // end CrearCadenaDeConexion
 
        private void LimpiarPantalla() {
            txtCodigo.Text = null;
            txtNombre.Text = null;
            txtApellido.Text = null;
            txtDocumentoNro.Text = null;
            txtDireccion.Text = null;
            txtTelefono.Text = null;
            txtEmail.Text = null;
            lblNotificacion.Text = null;
        } // end LimpiarPantalla;
 
        protected void btnGuardar_Click(object sender, EventArgs e)
        {
            // creamos la cadena para conectarnos a sql server
            CrearCadenaDeConexion();
            // instanciamos el objeto de conexion
            sqlConn = new System.Data.SqlClient.SqlConnection(ConnString);
            // instaciamos el objeto de comando
            sqlComando = new System.Data.SqlClient.SqlCommand();
            // asignametros atributos del command
            sqlComando.CommandType = CommandType.StoredProcedure;
            sqlComando.CommandText = "AltaPersona";
            sqlComando.CommandTimeout = 0;
            sqlComando.Connection = sqlConn;
 
            // Asignamos los parametros a enviar a la bd
            sqlComando.Parameters.AddWithValue("Nombre", Convert.ToString(txtNombre.Text));
            sqlComando.Parameters.AddWithValue("Apellido", Convert.ToString(txtApellido.Text));
            sqlComando.Parameters.AddWithValue("DocumentoNro", Convert.ToString(txtDocumentoNro.Text));
            sqlComando.Parameters.AddWithValue("Direccion", Convert.ToString(txtDireccion.Text));
            sqlComando.Parameters.AddWithValue("Telefono", Convert.ToString(txtTelefono.Text));
            sqlComando.Parameters.AddWithValue("Email", Convert.ToString(txtEmail.Text));
 
            // intentar ejecutar el alta
            try
            {
                // abrir la conexion
                if (sqlConn.State != ConnectionState.Open)
                    sqlConn.Open();
                // ejecutar el comando
                sqlComando.ExecuteNonQuery();
                // limpiar la pantalla
                LimpiarPantalla();
                // emitir el mensaje
                lblNotificacion.Text = "Guardado Correctamente!";
            }
            catch (Exception ex)
            { lblNotificacion.Text = ex.Message; }
            finally
            { sqlConn.Close(); sqlConn.Dispose(); }
        } // end btnGuardar_Click
 
        protected void btnLimpiar_Click(object sender, EventArgs e)
        {
            LimpiarPantalla();
        }
 
        protected void btnConsultar_Click(object sender, EventArgs e)
        {
            if (txtCodigo.Text == null)
            {
                lblNotificacion.Text = "Cargue un Codigo!";
            }
            else
            {
                // creamos la cadena para conectarnos a sql server
                CrearCadenaDeConexion();
                // instanciamos el objeto de conexion
                sqlConn = new System.Data.SqlClient.SqlConnection(ConnString);
                // instaciamos el objeto de comando
                sqlComando = new System.Data.SqlClient.SqlCommand();
                // asignametros atributos del command
                sqlComando.CommandType = CommandType.StoredProcedure;
                sqlComando.CommandText = "BuscarPersona";
                sqlComando.CommandTimeout = 0;
                sqlComando.Connection = sqlConn;
 
                // Asignamos los parametros a enviar a la bd
                sqlComando.Parameters.AddWithValue("Codigo", Convert.ToInt32(txtCodigo.Text));
 
                // intentar ejecutar el alta
                try
                {
                    // abrir la conexion
                    if (sqlConn.State != ConnectionState.Open)
                         sqlConn.Open();
                    // cargamos el datareader
                    sqlReader = sqlComando.ExecuteReader();
                    // si tiene datos la consulta cargarlos
                    if (sqlReader.HasRows)
                    {
                        txtNombre.Text = sqlReader.GetString(1);
                        txtApellido.Text = sqlReader.GetString(2);
                        txtDocumentoNro.Text = sqlReader.GetString(3);
                        txtDireccion.Text = sqlReader.GetString(4);
                        txtTelefono.Text = sqlReader.GetString(5);
                        txtEmail.Text = sqlReader.GetString(6);
                    }
                    else
                    {
                        lblNotificacion.Text = "No existe la Persona Buscada";
                    }
                }
                catch (Exception ex)
                { lblNotificacion.Text = ex.Message; }
                finally
                {
                    // cerrar y destruir
                    sqlConn.Close();
                    sqlConn.Dispose();
                }
            }
        } // end btnConsultar_Click
    }
}

Ahora para ejecutarlo deben asegurarse de tener el Apache Tomcat corriendo correctamente, y probarlo. Les dejo una captura del despliegue del ejemplo

Comentarios desde Facebook:

  1. avatar
    Elmer PERU Google Chrome Windows
    7 marzo 2013 at 12:34 #

    Hola GeekZero;
    Un favor estoy tratanado de descargar el programa, pero sale un error, crees que puedas enviarme el plugin por correo o compartirlo en la nube.
    Te adjunto el link donde sale el error:
    http://dev.mainsoft.com/Default.aspx?tabid=177

    Gracias,

  2. avatar
    henry Google Chrome Windows
    19 febrero 2011 at 03:12 #

    hola GeekZer si cuando instalo tambien me solicita un licencia , de donde puedo descargar dicha licencia

  3. avatar
    Angello PERU Internet Explorer Windows
    1 febrero 2011 at 12:19 #

    Cuando quiero utilizar el programa para java me pide licencia alguien me puede enviar la licencia Gracia

    • avatar
      Pedrito PARAGUAY Google Chrome Windows
      1 febrero 2011 at 13:39 #

      De que licencia hablas?

      • avatar
        Angello PERU Internet Explorer Windows
        1 febrero 2011 at 19:19 #

        Instale el programa Grasshopper para que corra el ASP para Java, ingreso al visual Studio 2008 y selecciono ASP For Java y me sale una ventanita que dice ingrese la licencia, donde la puedo conseguir o cuando la instalaste no te dijo esto.

        • avatar
          GeekZero PARAGUAY Google Chrome Windows
          1 febrero 2011 at 19:32 #

          He instalado varias veces y nunca me apareció tal cosa.. puedes subir algun print screen?

  4. avatar
    Viktor PERU Internet Explorer Windows
    12 junio 2010 at 09:01 #

    Gracias GeekZero, estoy revisando el generador de reportes q me pasaste y toy en la implentacion.

    Una consulta, como puedo enviar un email.

    te explico estoy generando un sys de atencion es y cuando se registras estas deben de enviar un mail al correo de tecnco asignado, y no me sale.

    me puedes ayudar

    Garcias men

    • avatar
      GeekZero Google Chrome Windows
      12 junio 2010 at 09:16 #

      Fijate aqúi como enviar Email con C# ya tenemos un post sobre el tema, sólo queda que prepares uses un Servidor de Correo con el protocolo SMTP habilitado (en el ejemplo muestro con Gmail) y que formatees el correo como necesitas..

  5. avatar
    Viktor PERU Internet Explorer Windows
    18 mayo 2010 at 18:20 #

    help

    estoy desarrollando un sys en web desde C# con sql y desplegando en apache tomcat sobre WXP

    y no he tenido mayor inconveninte hasta llgad alos reportes en Crystal Reports me sale el siguiente mensaje :

    Error 7 The return type 'CrystalDecisions.Web.CrystalReportViewer' of the method 'CrystalDecisions.Web.CrystalReportViewer ASP.rpt_webform1_aspx::__BuildControlCrystalReportViewer()' is not supported. c:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Filesweba65ff6e75678ef49App_Web_vgtcypxt.0.cs 16707566 1 Web

    y no puedo incluir el reporte en la solucion

    PF ayudaaaaaaaaaaaaaaaaaaaaaaaaaaaa

    • avatar
      GeekZero Google Chrome Windows
      18 mayo 2010 at 19:16 #

      Hola Viktor, lamento decirte que de momento no se puede usar de un modo oficial reportes de Crystal Report con Mono, lo puedes leer aqui: http://www.mono-project.com/FAQ:_Technical

      Por ser un reporteador propietario y de código cerrado, nadie está intentando implementar su uso de momento. Ciertamente utilizar mono tiene sus limitaciones. Si encuentras en algún lugar que alguien haya resuelto este problema nos gustaría que nos cuentes..

      De momento, con lo que puedo ayudarte es contarte sobre otras alternativas, ReportMan (este conozco y confio más en él) lo puedes descargar de acá: http://sourceforge.net/projects/reportman/

      La otra que nunca he utilizado por lo que no puedo recomendarte es FyiReporting: http://www.fyireporting.com/download.html

      Aunque me cuestiono algo, normalmente optamos por Mono cuando no disponemos de una licencia de Windows y por ende no podemos usar IIS, pero basado en tu comentario, lo estás desplegando en un Windows (Que supongo tiene licencia o si no la tiene, haces la vista gorda), teniendo eso en cuenta, porque no despliegas tu app sobre IIS directamente, será mucho más sencillo

  6. avatar
    GeekZero PARAGUAY Google Chrome Windows
    26 febrero 2010 at 15:17 #

    Me he fijado en el panel de estadisticas y definitivamente te guardo con SO Linux y Browser Firefox 3. 6
    Gracias la idea de todo es compartir el conocimiento 😀

  7. avatar
    GeekZero PARAGUAY Google Chrome Windows
    26 febrero 2010 at 15:12 #

    Fijate que en las estadisticas sen ven 2 items, una es tu sistema operativo que dice "Tu SO", y otro que es el que mas se usa para entrar al sitio que dice "Top SO".. y el algoritmo es capar de detectar SO's bastante viejos y hasta moviles 😀

  8. avatar
    LoBo_JeDi PERU Mozilla Firefox Linux
    26 febrero 2010 at 14:55 #

    Man te equivocastes de OS , yo uso Linux pero tu Estadistica dice XP, :DPor tu comentario es interesante.Saludos,

  9. avatar
    LoBo_JeDi PERU Mozilla Firefox Linux
    26 febrero 2010 at 14:52 #

    Man te equivocastes de OS , yo uso Linux pero tu Estadistica dice XP, 😀

    Por tu comentario es interesante.

    Saludos,

     

     

Responder