Codepoint

by Trentia Consulting

Solución a la hora de filtrar Foreign Keys con identificadores Guid en la grid de la suite de controles Telerik MVC Extensions

Seguramente los que hayáis trabajado con la suite de controles de Telerik para MVC os hayáis dado cuenta que determinados operaciones con los controles Grid no funcionan como deberían. Entre ellas, la más destacada y a la que no hemos encontrado solución hasta ahora, se trata del error que se producía a la hora de filtrar una grid con Foreign Keys donde la Primary Key eran identificadores únicos (Guid o Uniqueidentifier).

Parece ser que Telerik no ha querido darle la solución a esta problemática ya que este error se arrastra desde versiones muy iniciales de esta suite de controles y estoy seguro que no hemos sido los únicos que nos hemos encontrado con este problema.

Pues bien, después de darle vueltas al asunto,en Trentia Consulting no hemos tenido más remedio que darle solución y para ello hemos descargado el último código fuente y lo hemos modificado para dar solución al problema.

Aunque al final de esta entrada acompañamos el código fuente modificado para que los podáis compilar y actualizar a vuestra solución, hemos querido resaltar algunos pasos que creemos que son los más importantes.

Vamos a ello, principalmente cuando filtrábamos por una FK, la llamada AJAX que se encargaba de dibujar el GRID nos daba el siguiente error en la pila del Stack Trace

Invalid cast from "System.String" to "System.Guid" 
System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) +10578274 
	
System.String.System.IConvertible.ToType(Type type, IFormatProvider provider) +8 
	
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +10625268 

Con este error, deducimos que la la conversión de String a Guid no estaba implementada. Así que después de investigar, lo primero que tuvimos que tocar fue la clase FilterLexer ubicada dentro del namespace Telerik.Web.Mvc.Infrastructure.Implementation.

Revisando el método Tokenize vimos que el parse de parámetros Guid no estaba implementado, así que tuvimos que añadir lo siguiente:

 public IList Tokenize()
        {
            List tokens = new List();

            while (currentCharacterIndex < input.Length)
            {
                string result;

                if (TryParseGuid(out result))
                {
                    tokens.Add(UniqueIdentifier(result));
                }
                else if (TryParseIdentifier(out result))
                {
                    tokens.Add(Identifier(result));
                }
	...
}


Aquí hemos implementado el método TryParseGuid, que se encargará de detectar y formatear el string del identificador del filtro a Guid.

El código es el siguiente

private bool TryParseGuid(out string guid)
{
            SkipSeparators();

            int longitud=36;

            StringBuilder result = new StringBuilder();
            for (int i = 0; i < longitud; i++)
            {
                if((i + currentCharacterIndex)<input.Length)
                    result.Append(input[i + currentCharacterIndex]);
            }

          
            Guid outGuid = Guid.Empty;

            if (Guid.TryParse(result.ToString(), out outGuid))
            {
                guid = result.ToString();
                currentCharacterIndex+=longitud;
                return true;
            }
            else
            {
                guid = null;
                return false;
            }
}

Una vez implementada la detección del Guid, ya sólo nos queda ir al resto de clases que integran las funcionalidades de filtrado de la Grid de Telerik como la clase FilterParser.cs, GuidNode.cs y FilterTokenType.cs del mismo namespace.

Aquí os dejo el enlace de descarga del artículo que hemos redactado en CodeProject con el fin de compartir este problema con el mayor número de personas.

Descarga de la solución

Espero que os sea de ayuda.