Introduction
Surely those of you who have worked with Telerik for MVC controls suite have realized that certain operations with Grid controls do not work as they should. Among them, the most prominent and for which we have not found a solution so far, it's the error that occurs when filtering a grid with Foreign Keys where the Primary Key were unique identifiers (GUID or UniqueIdentifier).
It seems that Telerik has not wanted to give the solution to this problem giving the fact that this error has persisted since the very early versions of this suite of controls, and I am sure that we have not been the only ones that have encountered this problem.
Using the code
Well, after investigating this issue, in Trentia Consulting (http://www.trentia.es) we had no choice but to give solution and so we downloaded the latest source code of Telerik (http://telerikaspnetmvc.codeplex.com/) and we have modified it to provide a solution to the problem.
Although at the end of this entry we provide the modified source code so that you can compile and update to your solution, we wanted to highlight some steps that we believe are the most important.
Mainly when we filtered by a FK, the AJAX call which was responsible for drawing the GRID gave us the following error in the stack of 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
Telerik.Web.Mvc.Infrastructure.Implementation.Expressions.FilterDescriptorExpressionBuilder.
CreateValueExpression(Type targetType, Object value, CultureInfo culture) +355
Telerik.Web.Mvc.Infrastructure.Implementation.Expressions.FilterDescriptorExpressionBuilder.CreateBodyExpression() +149
Telerik.Web.Mvc.FilterDescriptor.CreateFilterExpression(ParameterExpression parameterExpression) +126
Telerik.Web.Mvc.FilterDescriptorBase.CreateFilterExpression(Expression instance) +143
Telerik.Web.Mvc.Infrastructure.Implementation.Expressions.FilterDescriptorCollectionExpressionBuilder.CreateBodyExpression() +149
Telerik.Web.Mvc.Infrastructure.Implementation.Expressions.FilterExpressionBuilder.CreateFilterExpression() +61
Telerik.Web.Mvc.Extensions.QueryableExtensions.Where(IQueryable source, IEnumerable`1 filterDescriptors) +216
With this error, we deduce that the conversion from String to GUID was not implemented. So after researching, the first thing we had to perform was
FilterLexer
, located within the Telerik.Web.Mvc.Infrastructure.Implementation
.
Reviewing the Tokenize
method we saw that the GUID parse parameter was not implemented, so we had to add
the TryParseGuid
method before the TryParseIdentifier
method as the following:
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));
}
...
}
}
Here we have implemented the method TryParseGuid
, which is in charge of detecting and formatting the string identifier of the GUID filter.
The code is as follows:
private bool TryParseGuid(out string guid)
{
SkipSeparators();
int len=36;
StringBuilder result = new StringBuilder();
for (int i = 0; i < len; 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+=len;
return true;
}
else
{
guid = null;
return false;
}
}
Points of Interest
Once implemented the GUID detection, we only have to go to other classes that integrate the filtering capabilities of Telerik Grid like
FilterParser.cs class, GuidNode.cs, and FilterTokenType.cs of the same namespace.
Here below you have the download link for the entire project
and where you can check the changes made.
I hope you find it helpful.