Guillermo G. Blog

Software Architect
ASP.NET MCP
"The best way to predict the future is to invent it"
Image: The only valid measurement of code quality


A funny image that shows a "cruel reality" of software development, and a curious form for calculate code quality.

This image was taken from Rodrigo Corral Blog and the original post it's called "Métrica de calidad de código".

How many WTFs / min have their revisions of quality control?

Tip: Hashtable vs SortedList

I wrote this short tip based in a question made from a workmate about a functionality that he wanted that appears in a Hashtable class.

Remember that a Hashtable represents a collection of key/value pairs that are organized based on the hash code of the key, and when a element is added to the Hashtable it's stored based on the hash code of the key, and the elements don't preserves the order based in their insertion to the Hashtable's "bag". If I want to retrieve the elements in the same order that they were placed, there's no way to retrieve them (normally).

And, if I want a collection class which can add key/value elements, and it maintains all the items sorted based in the insertion order? This class exists and their name is SortedList.

A SortedList is a collection of key/value pairs that is sorted by the keys and are accessible by key and by index.

If you want that the items contained in a collection always be "sorted" you need to use a SortedList instead a HashTable. If you don need the items sorted then use a HashTable, beacuse it's more faster than a SortedList obtaining a value from their "bag".

Updated 01-08-2008
An interesting performance test to compare four different implementations of the IDictionary interface posted by Vladimir Bodurov (IDictionary options - performance test - SortedList vs. SortedDictionary vs. Dictionary vs. Hashtable).

Artículo: ¿Documentos o Ejecutables?

Siempre unos de los principales "karmas" de los desarrolladores ha sido la documentación, ¿hasta que punto un proyecto de software debe contemplar un excesivo detalle de generación y mantenimiento de documentación y no perder el norte que es la elaboración de un paquete de software funcional que cumpla con los requisitos y necesidades planteados por el cliente?

A continuación les comparto un interesante post publicado por Rodrigo Corral denominado Documentos o Ejecutables en el cual hace énfasis a lo indicado en el párrafo anterior y que me parece es uno de los eternos dolores de cabeza que se presentan en un grupo de desarrollo de software .

¿Buen documentador o buen desarrollador?

Posted: Feb 11 2008, 10:41 AM by gugonzar | with no comments
Filed under:
Tip: DataSet.HasChanges and Windows Form Close Button Strange Behavior

I had to write a simple Windows Forms application that haves a form. This form contains a DataGridView control that is binded with a DataSet; this DataSet is filled with data from an XML file. This Windows Forms contains two buttons: "Accept Changes" and "Cancel Changes".

The "Accept Changes" and "Cancel Changes" buttons works greatly, the first one writes the content of the DataGridView control in a XML DataSet, and the second one simply cancel the data insertion, delete or modifying operation and shows a message indicating to the user if wants to discard or save all changes made to the DataGridView control. Both the "Cancel Changes" and the standard window close button executes the following method:

1: private void CloseWindow()
2: {
3:  dvProviders = dgvProviders.DataSource as DataView;
4:  DataSet dsProviders = dvProviders.Table.DataSet;
5:   
6:  if (dsProviders.HasChanges())
7:  {
8:   DialogResult saveChanges = MessageBox.Show("¿Save Changes?",
9:   "Save", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
10:   
11:   if saveChanges == DialogResult.Yes)
12:   {
13:    //Save the changes from the DataSet to an XML file
14:    this.SaveChanges();
15:   }
16:  }
17: }

But what happens if the user close the window using the standard window's close button and the DataGridView's DataSource (a DataSet) have pending changes?
It is expected that the button execute the CloseWindow method and detect if the DataSet has changes, but in a rare way when the code ask for the result of the DataSet's HasChanges method, it returns a false value and all the changes made in the DataGridView control are lost when the window close.

Well, Fortunately with the help of a coworker that told me that it was a "Bug" or better called "Windows Form's rare behavior". He told me that I need to move the focus of the DataGridView control to other control in the form (for example the Accept Changes button) before asking for the DataSet's HasChanges method, this way the DataGridView control apply the changes to the DataSet and the HasChanges return true (if any change is made to the DataGridView control) and the method's execution continues normally.

  5:     // Set the focus to other control
  6:      btnAcceptChanges.Focus();
  7:      
  8:      if (dsProviders.HasChanges())
  9:      {
 10:      ...

Thanks to Alberto Puyana for help me find the answer to this windows close button strange behavior.

Posted: Jan 22 2008, 09:12 AM by gugonzar | with 4 comment(s)
Filed under: , , ,
Articulo: ¿Como saber quien es un buen desarrollador?

code

Un interesante post publicado por Rodrigo Corral con algunos tips planteados sobre los aspectos que él considera debe tener un buen desarrollador.

¿Que tan buen desarrollador eres?

Articulo: ¿Como incrementar la seguridad en sitios web que permiten upload de archivos?

 asp.net

Un interesante articulo escrito por Scott Mitchell en el que nos brinda algunas consideraciones de seguridad muy importantes al momento de implementar funcionalidad para realizar upload de archivos sin atentar contra la seguridad de la aplicación.

Los invito entonces para que le den un vistazo a Another Potential Gotcha When Creating a Website that Allows Users to Share Uploaded Files y lo pongan en practica en sus desarrollos Web.

¿Que tan seguros son tus sitios?

AJAX: Como crear una ventana modal "Procesando..." utilizando los controles UpdateProgress y ModalPopup

ajax

Hace algunos días me vi en la necesidad de implementar en una aplicación Web que estaba desarrollando, funcionalidad basada en la tecnología AJAX. Cuando se hace una petición al servidor haciendo clic sobre un control de la página, al estar trabajando con AJAX la sensación de PostBack de la pagina desaparece y algunas veces es imperceptible detectar que la página se encuentra procesando el requerimiento con base en el evento generado.

Existe un control de ASP.net AJAX que nos permite presentarle al usuario un indicador de progreso de la petición denominado UpdateProgress, a pesar de ser muy útil para "controlar" la paciencia de los usuarios, se puede continuar interactuado con los demás controles de la aplicación lo que puede ocasionar comportamientos extraños en la aplicación. 

// Ejemplo de implementación de un UpdateProgress 
<asp:UpdateProgress ID="UpdateProg1" DisplayAfter="0" runat="server"> 
  <ProgressTemplate> 
    <div style="position: relative; top: 30%; text-align: center;">  
     <img src="loading.gif" style="vertical-align:middle" alt="Procesando"/> 
      Procesando ... 
    </div> 
  </ProgressTemplate> 
</asp:UpdateProgress> 

Desafortunadamente no existe un control de ASP.net AJAX que "bloquee" el contexto gráfico de la aplicación mientras se hace una petición de PostBack, pero afortunadamente se puede hacer una combinación exitosa utilizando otro control del AJAX Control Toolkit llamado ModalPopup Extender, el cual permite presentar un contenido con apariencia modal evitando que el usuario pueda interactuar con el contenido de la pagina desde la cual fue llamado.

//Ejemplo de implementación de un Modal Popup Extender 
<ajaxToolkit:ModalPopupExtender ID="ModalProgress" 
runat="server" TargetControlID="panelUpdateProgress"  
BackgroundCssClass="modalBackground" PopupControlID="panelUpdateProgress" /> 

Ahora viene la parte que interesante, tomar la ventaja de cada uno de los controles para crear una funcionalidad que presente un indicador de progreso al cliente pero que al mismo tiempo que la presenta de manera modal, con el fin de evitar que el usuario pueda interactuar con la pagina que originó el evento AJAX. El siguiente ejemplo de código presenta como realizar esta implementación:

// Como estamos utilizando ASP.net AJAX debemos se deben incluir las 
// siguientes directivas de registro en la pagina
<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI"
TagPrefix="asp" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
TagPrefix="ajaxToolkit" %>
// Incluir la etiqueta ScriptManager encargada de brindarle los scripts y 
// librerías necesarias para el funcionamiento de AJAX 
<asp:ScriptManager ID="ScriptManager1" runat="server" /> 
 
// Incorporamos el UpdateProgress dentro de un control Panel 
// y luego el ModalPopupExtender 
<asp:Panel ID="panelUpdateProgress" runat="server" 
CssClass="updateProgress"> 
    <asp:UpdateProgress ID="UpdateProg1" DisplayAfter="0" runat="server"> 
      <ProgressTemplate> 
        <div style="position: relative; top: 30%; text-align: center;"> 
          <img src="loading.gif" style="vertical-align: middle" 
          alt="Procesando" /> 
          Procesando ... 
        </div> 
      </ProgressTemplate> 
    </asp:UpdateProgress> 
  </asp:Panel> 
<ajaxToolkit:ModalPopupExtender ID="ModalProgress" runat="server" 
TargetControlID="panelUpdateProgress" BackgroundCssClass="modalBackground" 
PopupControlID="panelUpdateProgress" />

Se hace necesario adicionar utilizando lenguaje JavaScript dos funciones, que se deben ejecutar en las peticiones inicial y final de AJAX

//Código JavaScript incluido en un archivo denominado jsUpdateProgress.js 
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginReq); 
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endReq);    
function beginReq(sender, args){ 
    // muestra el popup 
    $find(ModalProgress).show();        
} 
 
function endReq(sender, args) { 
    //  esconde el popup 
    $find(ModalProgress).hide(); 
} 

Si se observa en las funciones de JavaScript se hace Referencia a la variable ModalProgress la cual debe ser creada desde el code-behind para que luego pueda ser utilizada por javascript, en el siguiente trozo de código se muestra como se crea la variable javascript desde el code-behind y se hace la referencia al archivo javascript con las funciones.

<script type="text/javascript" language="javascript"> 
      var ModalProgress ='<%= ModalProgress.ClientID %>';         
</script> 
 
<script type="text/javascript" src="jsUpdateProgress.js"></script>

Por ultimo le agregamos un poco de CSS con el fin de tener la ventana modal con un contorno gris y formato general para la imagen, y el texto contenido

.modalBackground 
{ 
    background-color: Gray; 
    filter: alpha(opacity=50); 
    opacity: 0.50; 
} 
 
.updateProgress 
{ 
    border-width: 1px; 
    border-style: solid; 
    background-color: #FFFFFF; 
    position: absolute; 
    width: 180px; 
    height: 65px; 
} 
 

Aquí terminamos con la elaboración de una ventana modal que muestra el mensaje de "Procesando..." mientras se hace una petición utilizando ASP.net AJAX.

El codigo fuente del ejemplo para que lo descargues y puedas ponerlo en práctica en tus aplicaciones.

Actualizado (Septiembre 02 de 2009): Ya hay una versión para Visual Basic incluida en el código de ejemplo.

Tip: Cast using the as Statement and Convert class vs Normal Casting

blackboard

Convert data from a DataType to another is a daily task of a developer; the applications require show formatted data (i.e Dates, currency, etc.) or make operations with this data. Here I'll show you an easy tip to avoid (or minimize) the use of try ... catch sentences when you need to do a casting or data conversion.

Normally to convert a numerical DataType to a string DataType (for example), we use the ToString() native method of the object. It's so easy and is the "natural" way to do it, but, what happens if the ToString() method can't do the conversion? It throws an Exception !!!

string
mySessionValue = Session["myKey"].ToString();
// if Session["myKey"] doesn't exists it throws an exception trying to convert null
// to string DataType.

Ok, a simple solution is to do the conversion using the as statement, this way it avoids to throw an exception if an error occurred when it's trying to do the conversion and a null value is assigned to mySessionValue variable.

string mySessionValue = Session["myKey"] as string;
// if Session["myKey"] doesn't exists it don't throw an exception trying to convert
//
null to string DataType.

Another valid solution using the ToString() method of the Convert class ...

string mySessionValue = Convert.ToString(Session["myKey"]);
// if Session["myKey"] doesn't exists it don't throw an exception trying to convert
//
null to string DataType.

And ... It's better to ask for a null value ...

if (string.IsNullOrEmpty(mySessionValue))
{
   // some code ...
}

Than to wrap the code with a try catch sentence.

try
{
   
string mySessionValue = Session["myKey"].ToString();
}
catch (InvalidCastException ex)
{
   
// Do something
}

I hope that this little and easy tip helps you to write better code.

Posted: Dec 05 2007, 11:46 AM by gugonzar | with no comments
Filed under: , , ,
Welcome to my Blog
I'm proud to announce the creation of my personal Blog. Here, I want to post information about ASP.net, AJAX, CSS, C# and others technologies related with the Microsoft .Net Framework, Design and Development Tips.

Thanks for coming to my Blog.

Any suggestion will be well attended.
 
Guillermo G.


 

More Posts « Previous page