miércoles, abril 20, 2011

Hacer post a una URL externa

En C# podemos utilizar el siguiente código para simular un post a una URL externa para, por ejemplo, saltarnos la página de login si conocemos los datos.


            string FormName = "loginForm";
            string Method = "post";
            string Url = "http://www.workshop-data.com/login.do";
 
            System.Web.HttpContext.Current.Response.Clear();
            System.Web.HttpContext.Current.Response.Write("");
            System.Web.HttpContext.Current.Response.Write(string.Format("", FormName));
            System.Web.HttpContext.Current.Response.Write(string.Format("", FormName, Method, Url));
            System.Web.HttpContext.Current.Response.Write(string.Format("""demouser""false"));
            System.Web.HttpContext.Current.Response.Write(string.Format("""username""xxx"));
            System.Web.HttpContext.Current.Response.Write(string.Format("""password""xxxxxx"));
            System.Web.HttpContext.Current.Response.Write("");
            System.Web.HttpContext.Current.Response.Write("");
            System.Web.HttpContext.Current.Response.End();
 
 
En este caso, estaríamos haciendo un post a www.workshop-data.com desde su pantalla de login pasándole un formulario con los datos pertinentes (usuario y password).

Para averiguar cómo se llama el formulario (en mi caso loginForm) y los campos, se puede utilizar Firebug (ver https://addons.mozilla.org/es-ES/firefox/addon/firebug/).

NOTA: Más info en http://www.c-sharpcorner.com/uploadfile/desaijm/asp.netposturl11282005005516am/asp.netposturl.aspx

viernes, abril 01, 2011

Aplicación web de datos dinámicos

Crear un mantenimiento simple a partir de un conjunto de tablas relacionadas de una base datos SQL es sencillo y rápido en ASP.Net. Pasos a seguir:

  1. Crear un nuevo proyecto de tipo Aplicación web de Linq to SQL (datos dinámicos ASP.NET).
  2. En la pestaña de Explorador de servidores añadir una conexión de datos a la B.DD que nos interesa.
  3. Añadir al proyecto un nuevo elemento de tipo Clases de LINQ to SQL.
  4. En el editor gráfico arrastrar desde la conexión de datos los objectos deseados.
  5. En el fichero Global.asax cambiar "YourDataContextType" por el nuevo tipo de contexto creado en el punto 3, y sustituir ScaffoldAllTables = false por ScaffoldAllTables = true.
... Y listo.

Muestra:

martes, febrero 08, 2011

Control de versiones con Subversion

En primer lugar, ¿qué es/para qué sirve?

Como su propio nombre indica se trata de un software que ayuda a llevar el control de versiones de cualquier aplicación que desarrollemos (es independiente de la plataforma de programación). Facilita la gestión de versiones y mantiene un registro de todos los cambios que se van realizando, con la posibilidad de echarlos atrás en cualquier momento. En entornos en los que trabajan varias personas en un mismo proyecto, es muy recomendable utilizar algo como esto porque permite que cada uno trabaje con una porción del proyecto sin peligro de que el que grabe último machaque las modificaciones de los demás.
 

El repositorio


El repositorio es el almacén del control de versiones. En nuestro caso lo he ubicado en http://192.168.1.187/svn, y en el servidor es E:\SVN. Esta carpeta no es ftp ni está compartida, sino que se trata de un recurso WebDav. Para tener acceso a este repositorio es necesario utilizar un usuario y password.

Si se entra en el repositorio desde el navegador, podréis moveros por una estructura similar a esta:

·         Repositories (raíz de todos los repositorios)
o   DotNetProjects (la carpeta que he creado para alojar los proyectos de .Net)
§  GestInc (el Portal de Gestión de Incidencias Informáticas)
·         trunk (versión actual)
·         tags
o   v1.0 (versión 1.0, foto, no modificar)
·         branches
§  SorteoYofindo.
·         trunk (versión actual)
·         tags
o   v1.0 (versión 1.0, foto, no modificar)
·         branches (para parches)


Aplicaciones en el servidor

En el servidor 192.168.1.187 he instalado 2 aplicaciones (gratuitas):
·         VisualSVN Server, que nos ayuda a gestionar el repositorio. Tiene una consola y un cliente web. Algunas de las cosas para las que va bien:
o   Crear la estructura para alojar un nuevo proyecto (crea las carpetas trunk, tags y branckes)
o   Gestión de usuarios

·         TortoiseSVN. Plugin para el explorador de Windows, que permite facilita:
o   Añadir cualquier documento/fichero al repositorio, mediante la opción Import


Ambas aplicaciones son clientes para Subversion, el “core” del meollo y pueden convivir sin problemas.


Aplicaciones cliente

·         TortoiseSVN, la misma del servidor, en realidad está más pensada para cliente, permitiendo:
o   Obtener cualquier versión de un proyecto/documento/fichero.
o   Comparar versiones
o   Hacer merge de versiones
o   Etc.
·         Plugins para Visual Studio, Eclipse (por si tenemos que hacer algo para Android), etc. En el caso del que me instalado para Visual Studio 2010 (AnkhSVN), permite hacer, entre otras cosas:
o   Abrir una versión de un proyecto del repositorio
o   Hacer Ckeckin/checkout/merge/etc. Ejemplo de modificación de un fichero + “commit changes

jueves, febrero 03, 2011

Aplicaciones abiertas

En muchos proyectos de Tecnologías de la Información tendemos a reinventar la rueda, a invertir tiempo del equipo de desarrollo en reinventar los gestores de contenidos, los blogs, el comercio electrónico… Estos proyectos han sido hechos y rehechos en cientos de ocasiones por diferentes equipos.
Durante todo este tiempo, la comunidad de desarrolladores ha creado iniciativas de colaboración alrededor de estas temáticas. Estos proyectos de la comunidad no son juguetes, son proyectos con cientos de horas de desarrollo invertidas y gran número de implantaciones por todo el mundo. Son gratuitos y altamente personalizables a través de plantillas, aunque en caso de necesitarlo tienen el código fuente disponible para que podamos hacer algún ajuste para nuestro proyecto.
Aquí tienes un pequeño resumen de las aplicaciones web gratuitas más utilizadas. Y recuerda… si ya existe, ¿por qué reinventarlo?


Umbraco CMS es un gestor de contenidos utilizado en más de 85000 sitios web. Es muy fácil de utilizar y de extender, además de las posibilidades de integración con sistemas existentes. Umbraco está basado en tecnología .NET


Wordpress comenzó en el año 2003 como un proyecto para mejorar la tipografía y con pocos usuarios. Desde entonces ha crecido para convertirse en la herramienta de blogging más utilizada del mundo, cientos de miles de sitios con decenas de millones de usuarios en todo el mundo. Wordpress está basado en tecnología PHP.


Joomla! Es un gestor de contenidos de código abierto. Su potente framework para aplicaciones facilita la creación de plugins para extender su funcionalidad a Nuevo ámbitos. La funcionalidad básica de Joomla! facilita la creción de sistemas de inventarios, generación de informes, catálogos de productos, sistemas de e-commerce, directories de necogios y muchos más escenarios. Joomla! esta basado en tecnología PHP.

nopCommerce es la solución lider para comercio electrónico basada en ASP.NET. nopCommerce se puede utilizer y configurar por cualquiera con mínimos conocimientos sobre web y ordenadores. Es una solución segura, escalabrla y extensible. Tiene una sencilla herramienta de administración para gestionar el frontal, clientes, listas, descuentos,… además de soporte multilingüe y multidivisa.

¡Y muchas más!
BlogEngine.NETDrupalScrewTurnWikiMoodledotNetNukeOrchard CMS… seguro que alguna se ajusta a tus necesidades.

Para simplificar la instalación de estos proyectos y sus dependencias, los hemos recogido y empaquetado en una Galería de Aplicaciones Web donde puedes escoger la que más se ajuste a tus necesidades.
Videos Relacionados
Instalación nopCommerce
Instalación Joomla
Instalación Wordpress
Instalación Umbraco
Instalación ScrewTurnWiki
Instalacion Drupal

Además, puedes utilizar la herramientaWebMatrix para descargar la aplicación que prefieras, modificarla y posteriormente publicarla en internet
Wordpress via Webmatrix
Umbraco CMS via WebMatrix
nopCommerce via WebMatrix



martes, enero 25, 2011

Uso de tuplas de C#

Ejemplo de definición de una función que retorna una tupla:


/// 
/// Retorna la asignación (técnico y mail) asociado a cierto tipo de elemento (equipamiento), o, en su defecto, de la categoría a la que pertenece.
/// 
/// Categoría del elemento
/// Tipo del elemento
/// Tupla Técnico/MailTo
public Tuple<Userstring> GetAssignmentForEquipmentType(string equipmentCategoryID, string equipmentTypeID)
{
    using (AIMModelConnection dc = new AIMModelConnection())
    {
        var query =
            from p in dc.EquipmentAssignments
            where (p.EquipmentCategoryID == equipmentCategoryID && p.EquipmentTypeID == equipmentTypeID) || (p.EquipmentCategoryID == equipmentCategoryID && p.EquipmentTypeID == null)
            orderby p.EquipmentCategoryID, p.EquipmentTypeID descending
            select p;
 
        EquipmentAssignment assignment = query.FirstOrDefault<EquipmentAssignment>();
 
        if (assignment != null)
            return Tuple.Create<Userstring>(assignment.User, assignment.CopyMailTo);
        else
            return null;
    }
}


... Y uso

// Obtener asignación en función de categoría y tipo del elemento afectado.
Tuple<Userstring> assignment = GetAssignmentForEquipmentType(equipmentCategory, equipmentType);

if (assignment != null)
{
    if (assignment.Item1 != null)
        this.txtAssignedTo.Text = assignment.Item1.UserName;

    if (assignment.Item2 != null)
        this.txtMailTo.Text = assignment.Item2;
}

viernes, enero 21, 2011

Otra forma de establecer/cambiar en tiempo de ejecución el valor de cualquier propiedad (Texto, Color, Icono...) de una celda de un GridView de ASP.Net

/// Método de evento de la columna State del grid, para modificar su valor (pasarlo a texto)
/// y su color en función del valor.
/// Se llama utilizando la propiedad Text='<%# Eval("State")%>', 
/// de un asp:Label, de un ItemTemplate, de un asp:TemplateField, del asp:GridView
protected void gridViewLabelState_Load(object sender, EventArgs e)
{
    Incident.StateEnum state = (Incident.StateEnum)int.Parse(((Label)sender).Text);

    ((Label)sender).ForeColor = IncidentStateColor.GetStateColor(state);
    ((Label)sender).Text = Incident.IncidentStateEnumToString((Incident.StateEnum)state);
}

Cómo establecer/cambiar en tiempo de ejecución el valor de cualquier propiedad (Texto, Color, Icono...) de una celda de un GridView de ASP.Net

A continuación un ejemplo de un grid con 2 columnas configuradas para que:
1ª) Muestre un texto y un color dependiendo del valor de un campo numérico.
2ª) Muestre una imagen en función del valor de 2 campos. 

[MiPagina.aspx (Diseño de página)] 


<asp:GridView ID="grdIncidents" runat="server" CellPadding="4" ForeColor="#333333"
    GridLines="None" AutoGenerateColumns="False" DataKeyNames="ID" AllowPaging="False"
    AllowSorting="True" Width="100%" CssClass="GridViewStyle">
    <Columns>
        <asp:TemplateField HeaderText="Estado" HeaderStyle-HorizontalAlign="Left">
            <ItemTemplate>
                <asp:Label ID="gridViewLabelState" DataField="State" runat="server" 
                    ForeColor='<%# GetStateColor(Eval("State"))%>' 
                    Text='<%# IncidentStateToString(Eval("State"))%>'/>
            ItemTemplate>
        asp:TemplateField>
        <asp:TemplateField HeaderText="" HeaderStyle-HorizontalAlign="Left">
            <ItemTemplate>
                <asp:Image ID="gridViewImageSemaforo" runat="server" 
                    ImageUrl='<%# GetSemaphoreImageUrl(Eval("State"), Eval("CreationDate"))%>' />
            ItemTemplate>
        asp:TemplateField>
    Columns>
asp:GridView>


[MiPagina.aspx.cs (Code behind)]

/// Método llamado desde la pantalla para convertir la columna State a texto.
protected string IncidentStateToString(object state)
{
    return Incident.IncidentStateEnumToString((Incident.StateEnum)state);
}

/// Método llamado desde la página para cambiar el color de un State.
protected System.Drawing.Color GetStateColor(object state)
{
    return IncidentStateColor.GetStateColor((Incident.StateEnum)state);
}

/// Método llamado desde la página para establecer el semáforo a partir del estado y
/// la fecha de creación.
/// Si la incidencia está esperando por un Técnico y lleva abierta más de 1 semana => Rojo!
/// Si la incidencia está esperando por un Técnico pero NO lleva abierta más de 1 semana => Ámbar
/// En cualquier otro caso (la incidencia no está esperando por un Técnico)
/// Estado de la incidencia
/// Fecha de creación de la incidencia
/// String de la url de la imagen del semáforo que toque.
protected string GetSemaphoreImageUrl(object state, object creationDate)
{
    // Si la incidencia está esperando por un Técnico...
    if (Incident.GetStatesFromStatus(Incident.StatusEnum.WaitingForTechnic).Contains<int>((int)state))
        //...y abierta desde hace más de 1 semana => Rojo!
        if (DateTime.Compare( ((DateTime)creationDate).AddDays(7), DateTime.Now)>0)
            return "Resources/semaphoreRed.png";
        //...y abierta desde hace menos de 1 semana => Ámbar
        else
            return "Resources/semaphoreYellow.png";

    // En caso contrario (la incidencia no está esperando por un Técnico)
    else
        return "Resources/semaphoreGreen.png";
}

martes, enero 11, 2011

Llenar un DataGridView sin usar Dataset (Populate a DataGridView without a DataSet)

Podemos llenar un DataGridView asignando a su DataSource una lista de objetos tal como se muestra en el ejemplo 1.


Nota: Los objetos deben exponer sus propiedades mediante construcciones get/set. Aquellas propiedades que no se expongan así, no se mostrarán en el DataGridView aunque sean públicas.


Una forma alternativa sería crear una clase que derive de IListSource (por ejemplo) e implementar el método GetList(), tal como se muestra en el ejemplo 2. Podemos crear un método Add(). En este caso el argumento estará tipado, cosa que en el anterior aceptaba cualquier tipo derivado de Object.


El interface IBindingList aportará funcionalidad extra con el DataGridView.


Un link con un ejemplo muy completo: http://msdn.microsoft.com/en-us/library/ms404297.aspx


Ejemplo 1:


Form_Load()

{

IList myBusinessObjectsList = new List();
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil B", "1..6"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil C", "1..7"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 3", "Perfil D", "1..8"));

this.dataGridView1.DataSource = myBusinessObjectsList;

}


public class MyBusinessObject
{

private string _group;
private string _perfil;
private string _range;
public string Group
{
get { return _group; }
set { _group = value; }
}
public string Perfil
{
get { return _perfil; }
set { _perfil = value; }
}
public string Range
{
get { return _range; }
set { _range = value; }
}
public MyBusinessObject(string group, string perfil, string range)
{
Group = group;
Perfil = perfil;
Range = range;
}
}


Ejemplo 2:


private void Form_Load(object sender, EventArgs e)
{
MyBusinessObjectsList myBusinessObjectsList = new MyBusinessObjectsList();
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 1", "Perfil B", "1..6"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil A", "1..5"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 2", "Perfil C", "1..7"));
myBusinessObjectsList.Add(new MyBusinessObject("Grupo 3", "Perfil D", "1..8"));
this.dataGridView1.DataSource = myBusinessObjectsList;
}


public class MyBusinessObjectsList: IListSource
{
List ls = new List();

#region IListSource Members
bool IListSource.ContainsListCollection
{
get { return false; }
}
System.Collections.IList IListSource.GetList()
{
return ls;
}
#endregion

public void Add(MyBusinessObject businessObject)
{
ls.Add(businessObject);
}
}

lunes, enero 10, 2011

Publicar aplicación

Desde Visual Studio 2010 es muy fácil "publicar" un proyecto (puede ser cualquier tipo de aplicación, web o desktop) utilizando la opción Generar / Publicar MiApp, tanto en una unidad compartida, como en un ftp o una web.

Por ejemplo:
Ubicación para la publicación: ftp://192.168.1.187/WWW/MiApp/.
Instalación: http://www.jaac.com/MiApp/

Al entrar desde un cliente a http://192.168.1.187/MiApp/publish.htm aparecerá un botón para iniciar la instalación de la aplicación, indicándonos los requisitos previos (versión de .Net Framework, etc)

Acceder a datos de una hoja excel

Para acceder a los datos de un excel podemos crear una función como la siguiente:

public DataTable GetExcel(string filename, string sheetName)
{
    OleDbConnection dbConn = null;
    DataTable resultTable = new DataTable(sheetName);

    // Build connection string.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
        "Data Source=" + filename +
        ";Extended Properties=Excel 8.0;";

    // Create connection and open it.
    dbConn = new OleDbConnection(connString);
    dbConn.Open();

    if (!sheetName.EndsWith("$"))
    {
        sheetName += '$';
    }
    string query = string.Format("SELECT * FROM [{0}]", sheetName);

    using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, dbConn))
    {
        adapter.Fill(resultTable);
    }

    return resultTable;
}

Y en nuestro código usarla así:

    […]


    DataTable clientes;
    clientes = GetExcel(Application.StartupPath + @"\MiExcel.xls", "Hoja1"); // Buscará el fichero donde esté el exe.

    int numFilas = clientes.Rows.Count; // Cuidado, la primera fila se considera de títulos!

    string nombre = clientes.Rows[5]["Nombre"].ToString(); // Valor de la fila 5 y columna con título “Nombre”.

    […]