Ariel Popovsky's Blog

Aventuras y desventuras con .net
posts - 7, comments - 33, trackbacks - 0

My Links

News

Locations of visitors to this page

Twitter












Tag Cloud

Archives

Post Categories

My Sites

Friday, August 14, 2009

Re-Installing Daemon Tools Lite (and SPTD) on Windows 7

After the update from Windows 7 RC to RTM I noticed Daemon Tools was gone. I tried to reinstall it but it was impossible.
Daemon Tools relies on SPTD (a SCSI pass through driver) to do it’s magic and it checks whether it is installed. It seems that it couldn’t detect it on my system so it launched the SPTD setup, asked to restart the computer and then again and again.

I downloaded a new version of SPTD (1.60) from the product page but I had the same problem, SPTD installed, asked me to restart and then couldn’t detect the installed driver.

Googling I found out many others had the same problem and Finally I found a post in a forum explaining that it was a registry permissions problem.

I removed SPTD manually, re-installed and then re-installed Daemon Tools without a problem.

Here are the steps to re-install SPTD on Windows 7:

1.) Open regedit. And find HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sptd.
2.) Delete that folder "sptd" in the registry. If you can't, just right-click the folder, and click Permissions. Ask for "Full Control". Do this also to a sub-folder of "sptd" namely "cfg" (i actually already deleted it so i forgot). Just find ways to delete the "sptd" folder in the registry.
3.) Now rename or delete the 'sptd.sys' file found on Windows\system32\drivers.
4.) Download the newest SPTD Layer version "http://www.duplexsecure.com/en/downloads". Install and wait for confirmation to reboot.
5.) After reboot. Try opening the SPTD layer installer again and see if it tells you that SPTD layer is already installed. If it says so, continue on installing your Alcohol 120 or Daemon Tools.

 

UPDATE: If you get “failed to open service key”…

I just upgraded my desktop to RTM, this time to x64 version and I got this error while running the SPTD setup. After some tests and reboots I figured out how to make it work.

Open regedit and look for this key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\LEGACY_SPTD, try to delete it. If you can’t, try this: go folder by folder (0000 and control), open the permissions dialog, go to advanced, Owner and take ownership of the folder. Don’t try to apply the owner recursively, you have to set it on each individual folder. Then, in the security tab grant full control to “everyone” (again, folder by folder). Now you should be able to delete it. I also deleted the same entry in ControlSet001 and ControlSet002.
Finally, just in case, delete this entry too: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\eventlog\System\sptd

Now run SPTD setup again, you should be able to install it and after a reboot install Daemon Tools.

Technorati Tags: ,

posted @ Friday, August 14, 2009 12:37 PM | Feedback (20) |

Monday, June 22, 2009

Exception/Error handling using the ObjectDataSource

This post was going to be a rant about how using the ObjectDataSource was impossible to handle exceptions thrown while retrieving or updating data. After some experiments and reading some misleading posts I saw only three possible ways:

  1. Use a generic error handler like the Page Error event or the Application Error event in global.asax.
  2. Implement handlers for the Updating, Selecting and Deleting events of the GridView bound to the datasource, set the event.Cancel to true and then manually call the Insert, Delete, Update and Select methods of the data source inside a try/catch block.
  3. Throw away the data source and do everything manually.

Luckily I accidentally found the right way to do it while looking at the EventArgs class properties for the Selected event. When the ObjectDataSource calls your data object, if the result is an exception it will call your post event event-handler (Selected, Deleted, etc). The EventArgs has two properties for managing exceptions, one is the Exception itself, the other is a boolean, ExceptionHandled. If you want to handle the exception you just need to set the ExceptionHandled property to true.

  1:         protected void MyDataSource_Deleted(object sender, ObjectDataSourceStatusEventArgs e)
  2:         {
  3:             if(e.Exception!=null)
  4:             {
  5:                 ShowMessage(Constants.GenericErrorMessage, MessageType.Error);
  6:                 e.ExceptionHandled = true;
  7:             }
  8:             else
  9:             {
 10:                 ShowMessage("Entity deleted successfully.", MessageType.Success);                    
 11:             }            
 12:         }

 

posted @ Monday, June 22, 2009 10:54 AM | Feedback (0) |

Tuesday, June 16, 2009

JQuery Autocomplete with WCF services

I was trying to implement a simple autocomplete behavior on a textbox using JQuery and the JQuery Autocomplete plugin but it wasn’t as simple as I expected. The basic idea was to get the options from a WCF web service as the user typed. The first obstacle was preparing the Service to accept the calls from the plugin. The plugin accepts a url as the data source and invokes it with two parameters (and a timestamp), q is the query and limit the maximum number of results to return, so I created the following method using some tips from Rick Strahl's weblog:

  1: 	[OperationContract]
  2: 	[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.WrappedRequest, 
  3: 		ResponseFormat = WebMessageFormat.Json)]
  4: 	public string[] GetOptions(string q, int limit)
  5: 	{
  6: 	     return new[]{"xxxx", "yyyy", "zzzz"};
  7: 	}

 

The service can now be invoked using the url: DataService.svc/GetOption?q=query&limit=10.

Setting up the autocomplete plugin is very straight forward:

  1: 	$(function(){
  2: 		$(".texbox").autocomplete("/Services/DataService.svc/GetOptions");
  3: 	});

 

The only problem was that I saw only one result, even when the JSON data had all of them. After some research I found out the problem was the parsing function used by the plugin. It doesn’t expects the kind of data the service returns, specially because the MS JSon serializer wraps up the JSON result in a “d” element (more about this here).

It’s not documented in the plugin options but as some others noticed you can provide your own parse function (I found out the hard way, reading the source). So I did (you also need to set the dataType to “json”:

   1:  $(function(){
   2:      $(".texbox").autocomplete("/Services/DataService.svc/GetOptions", {
   3:          dataType: 'json',
   4:          parse: function(data) {
   5:              var items = data.d;
   6:              var parsed=[];
   7:              for(var i=0;i<items.length;i++)
   8:                   parsed[i] = {
   9:                      data: [items[i]],
  10:                      value: items[i],
  11:                      result: [items[i]]
  12:                  }; 
  13:              return parsed;
  14:          }
  15:      });
  16:  });

 

This got my autocomplete behavior going.

Etiquetas de Technorati: ,,,

posted @ Tuesday, June 16, 2009 9:19 PM | Feedback (1) |

Monday, May 18, 2009

Using Flash with ASP.NET MVC and Authentication (re-loaded)

Matt liked my idea and wrapped the code in a reusable filter attribute. Cool idea, you've got to love the blogosphere.

http://trycatchfail.com/blog/post/2009/05/13/using-flash-with-aspnet-mvc-and-authentication.aspx

posted @ Monday, May 18, 2009 3:08 PM | Feedback (0) |

Wednesday, May 06, 2009

Working around Flash Cookie Bug in ASP.net MVC

I was integrating a JQuery plugin for file uploads, uploadify, in my app when I saw a very strange behavior. The plugin reported an error transmitting the file to the server and debugging the controller code I noticed the target action wasn’t being called at all. Debugging the client code I found out that the server was redirecting the upload to the login page. The Controller was marked with the AuthorizeAttribute but the user was already authenticated. After a google search I found this article explaining the problem and a workaround that didn’t work for me.

One easy solution was to remove the Authorize attribute from that action but that would open a big security hole, allowing anybody to upload files to the server. I finally implemented a manual authentication that seems to work fine.

In the client I extract the value from the forms authentication cookie and send it with my file as data:

 

  1:     var auth = "<% = Request.Cookies[FormsAuthentication.FormsCookieName]==null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>";   
  2: 
  3:     //File upload
  4:     $('#photoUpload').fileUpload({
  5:         uploader: '/Content/uploader.swf',
  6:         script: '/Files/UploadPicture',
  7:         scriptData: { token: auth },
  8:         cancelImg: '/Content/images/cancel.png',
  9:         auto: true,
 10:         folder: '/uploads',
 11:         fileDesc: 'Image',
 12:         fileExt: '*.jpg;*.jpeg;*.png;*.gif'
 13:     });
 14: 

I think this technique could be easily applied to SWFUpload as well.

The server receives the security token so I needed to authenticate it. This action does the trick:

  1:         public ActionResult UploadPicture(string token, HttpPostedFileBase fileData)
  2:         {
  3:             FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(token);
  4:             if(ticket!=null)
  5:             {
  6:                 var identity = new FormsIdentity(ticket);
  7:                 if(identity.IsAuthenticated)
  8:                 {
  9:                     /*************************************
 10:                      * 
 11:                      *          HANDLE FILE
 12:                      * 
 13:                      * ***********************************/
 14:                     return Content("OK");
 15:                 }
 16:             }
 17:             throw new InvalidOperationException("The user is not authenticated.");
 18:             
 19:         }
 20: 

 

I think I’ll move the authentication to an action filter to keep the action code cleaner but this works fine for now.

posted @ Wednesday, May 06, 2009 11:44 PM | Feedback (7) |

Wednesday, April 29, 2009

Creando un Validador Personalizado para NHibernate Validator

NOTA (2009-06-26): Existe una librería oficial de NHibernate Validator con validadores adicionales específicos para ciertos paises, NHibernate.Validator.Specific.dll (descargar) y ya cuenta con un validador de CUIT. Gracias Fabio Maulo por el dato.


La aplicación en la que estoy trabajando está basada en ASP.net MVC y utilizamos Sharp Architecture como base. Sharp Architecture utiliza a su vez NHibernate Validator para la validación de las entidades de negocio por lo que, continuando con el tema del post anterior, decidí armar un validador de CUIT/CUIL personalizado y aplicarlo en nuestras clases.

Crear una validador para Nhibernate Validator es muy simple, solo se requieren dos clases simples, el validador propiamente dicho y un atributo. Empecemos por el atributo:

   1:  [Serializable, ValidatorClass(typeof(CuitValidator)), 
   2:      AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
   3:  public class CuitAttribute : Attribute, IRuleArgs
   4:  {
   5:      private string message;
   6:      
   7:      public CuitAttribute()
   8:      {
   9:          this.message = Glossary.Validation_Cuit_Invalid;
  10:      }
  11:      
  12:      public string Message
  13:      {
  14:          get { return message; }
  15:          set { message = value; }
  16:      }
  17:  }

 

Lo más importante es que debemos implementar la Intefaz “IRuleArgs” provista por el framework de validación (además de extender Attribute) y aplicar a su vez el atributo “ValidatorClass” el que indica cual es la clase concreta encargada de realizar la validación para los miembros que tengan este atributo.

La clase en cuestión es también muy simple, implementa la interfaz “IValidator”, cuyo único método es IsValid. Recibe el valor del miembro a validar y debe devolver True si es válido o False si no.

En mi implementación solo necesito llamar a la clase creada en el post anterior:

   1:  [Serializable]
   2:  public class CuitValidator:IValidator
   3:  {
   4:      public bool IsValid(object value)
   5:      {
   6:          return value == null || 
   7:                 value.ToString()==string.Empty || 
   8:                 CuitHelper.ValidaCuit(value.ToString());
   9:      }
  10:  }

Notese que si el valor es nulo o vacio lo damos por válido. Esto se debe a que para validar si un campo es requerido contamos con atributos más específicos (NotNull, NotNullOrEmpty).

Solo resta aplicarlo:

   1:          /// <summary> 
   2:          /// CUIT/CUIL de la persona Juridica. 
   3:          /// </summary> 
   4:          [Cuit]

 

posted @ Wednesday, April 29, 2009 10:58 PM | Feedback (1) |

Monday, April 27, 2009

Validar un CUIT/CUIL con C#, Javascript y JQuery.Validate

Etiquetas de Technorati: ,,,,
 

Hace tiempo que quiero armar un blog técnico para compartir experiencias y cosas de interes para desarrolladores web y finalmente me decidí.
Para el primer post quiero empezar con algo útil que tuve que armar para una aplicación que estamos desarrollando. Se trata de rutinas de validación de CUIT/CUIL (Código Unico de Identificación Tributaria / Laboral de Argentina). Hay varios ejemplos en la web en distintos lenguajes pero al no ver algo en c# o Javascript decidí armar mi versión.
La validación se basa en calcular el dígito verificador y compararlo con el suministrado. El algoritmo es muy simple, se multiplica cada dígito por un factor específico, la suma de todos los términos se divide por 11 y el dígito es igual a 0 si el resto es 0, 9 si el resto es 1 o 11-resto en los demás casos.
Esta es la versión de .net para calcular el dígito:

 
   1:          /// <summary>
   2:          /// Calcula el dígito verificador dado un CUIT completo o sin él.
   3:          /// </summary>
   4:          /// <param name="cuit">El CUIT como String sin guiones</param>
   5:          /// <returns>El valor del dígito verificador calculado.</returns>
   6:          public static int CalcularDigitoCuit(string cuit)
   7:          {
   8:              int[] mult = new[] { 5, 4, 3, 2, 7, 6, 5, 4, 3, 2 };
   9:              char[] nums = cuit.ToCharArray();
  10:              int total = 0;
  11:              for (int i = 0; i < mult.Length; i++)
  12:              {
  13:                  total += int.Parse(nums[i].ToString()) * mult[i];
  14:              }
  15:              var resto = total % 11;
  16:              return resto == 0 ? 0 : resto == 1 ? 9 : 11 - resto;
  17:          }

 

El código para validar simplemente compara el dígito suministrado con el calculado. Como mejora se podrían validar los primeros 2 dígitos que solo pueden tener ciertos valores pero preferí dejarlo afuera por ahora ya que quien sabe si el día de mañana no se agregan otros códigos.

   1:          /// <summary>
   2:          /// Valida el CUIT ingresado.
   3:          /// </summary>
   4:          /// <param name="cuit" />Número de CUIT como string con o sin guiones
   5:          /// <returns>True si el CUIT es válido y False si no.</returns>
   6:          public static bool ValidaCuit(string cuit)
   7:          {
   8:              if (cuit == null)
   9:              {
  10:                  return false;
  11:              }
  12:              //Quito los guiones, el cuit resultante debe tener 11 caracteres.
  13:              cuit = cuit.Replace("-", string.Empty);
  14:              if (cuit.Length != 11)
  15:              {
  16:                  return false;
  17:              }
  18:              else
  19:              {
  20:                  int calculado = CalcularDigitoCuit(cuit);
  21:                  int digito = int.Parse(cuit.Substring(10));
  22:                  return calculado == digito;
  23:              }
  24:          }

 

 La versión Javascript es muy similar aunque no separé la generación del dígito de la validación. La última línea registra el método de validación en JQuery Validator.

   1:  function validaCuit(cuit) {
   2:      if (typeof (cuit) == 'undefined')
   3:          return true;
   4:      cuit = cuit.toString().replace(/[-_]/g, "");
   5:      if (cuit == '')
   6:          return true; //No estamos validando si el campo esta vacio, eso queda para el "required"
   7:      if (cuit.length != 11)
   8:          return false;
   9:      else {
  10:          var mult = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];
  11:          var total = 0;
  12:          for (var i = 0; i < mult.length; i++) {
  13:              total += parseInt(cuit[i]) * mult[i];
  14:          }
  15:          var mod = total % 11;
  16:          var digito = mod == 0 ? 0 : mod == 1 ? 9 : 11 - mod;
  17:      }
  18:      return digito == parseInt(cuit[10]);
  19:  }
  20:   
  21:  $.validator.addMethod("cuit", validaCuit, 'CUIT/CUIT Inválido');


Un ejemplo de uso del validador de Javascript:
   1:   <form id="test">
   2:      <input type="text" id="cuit" name="cuit" />
   3:   </form>

 

 

   1:      <script type="text/javascript">
   2:          $(function() {
   3:              $("#test").validate({
   4:                  rules: {
   5:                      cuit: "cuit"
   6:                  }
   7:              });
   8:              $("#cuit").keydown(function() {
   9:                  $(this).valid();
  10:              });
  11:          });
  12:      
  13:      </script>

Espero que a alguien le sea útil.

 

posted @ Monday, April 27, 2009 4:18 PM | Feedback (4) |

Powered by: