Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Lennart Stoop 304 posts 842 karma points
    Apr 14, 2011 @ 10:21
    Lennart Stoop
    0

    Text property treated as DateTime?

    Hi guys,

    I'm new to Razor and was hoping someone could help me understand this error?

    What I am trying to do is order a set of nodes based on a property which is of type Textstring. The property holds a string value which represents a timespan (e.g. 35:20 as in 35 minutes and 20 seconds). The issue I am experiencing is that in fact the property seems to be treated as a DateTime.

    Here's the razor code:

    @inherits umbraco.MacroEngines.DynamicNodeContext

    @
      var numberOfItems @Model.MaxHighscores
      var container @Model.HighscoreContainers.FirstOrDefault();
    }

    <h2>Top @numberOfItems</h2>

    <ol>
      @if (@container != null)
      {
        foreach (var highscore in @container.Highscores.OrderBy("participantScore").Take(numberOfItems){                                                                      
          <li>@highscore.ParticipantScore.ToString("HH:mm"@highscore.ParticipantName</li>
        }
      }
    </ol
    >

     

    This code will work for values between 00:00 and 23:59 but will fail for larger timespans as these cannot be stored within a DateTime object.

    Any ideas why the property is treated as a DateTime in the first place ?

     

     

    Cheers

    Lennart

  • Michael Latouche 504 posts 819 karma points MVP 4x c-trib
    Apr 14, 2011 @ 11:40
    Michael Latouche
    0

    Hi Lennart,

    I am no Razor expert eitehr, but as far as I can see from your code, I think the problem resides in the ToString("HH:mm") part. This is a date-time format, so you are basically telling Razor to format your ParticipantScore as an "Hour:minutes" format, which will indeed not work for 35:20.

    From what I understand from your post, your ParticipantScore is already formatted as "35:20", so maybe you could just output it, or else call "ToString()" but without any formatting?

    Hope this helps.

    Cheers,

    Michael.

  • Lennart Stoop 304 posts 842 karma points
    Apr 14, 2011 @ 12:30
    Lennart Stoop
    0

    Hi Michael,

    I'm temporarely using the DateTime formatter as the ParticipantScore seems strongly typed as DateTime (which is out of my control I reckon?)

    The error already occurs in the OrderBy method actually:

    Error Loading Razor Script (file: Highscores) Object must be of type DateTime.    at System.DateTime.CompareTo(Object value)
      at System.Collections.Comparer.Compare(Object a, Object b)
      at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
      at System.Linq.EnumerableSorter`2.CompareKeys(Int32 index1, Int32 index2)
      at System.Linq.EnumerableSorter`1.QuickSort(Int32[] map, Int32 left, Int32 right)
      at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
      at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
      at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
      at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
      at umbraco.MacroEngines.DynamicNodeList.TryInvokeMember(InvokeMemberBinder binder, Object[] args, Object& result)
      at CallSite.Target(Closure , CallSite , Object , String )
      at ASP._Page_macroScripts_Highscores_cshtml.Execute() in d:\Websites\Microsoft NL\nlwms042\macroScripts\Highscores.cshtml:line 13
      at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
      at System.Web.WebPages.WebPage.ExecutePageHierarchy(IEnumerable`1 executors)
      at System.Web.WebPages.WebPage.ExecutePageHierarchy()
      at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
      at umbraco.MacroEngines.RazorMacroEngine.ExecuteRazor(MacroModel macro, INode currentPage)
      at umbraco.MacroEngines.RazorMacroEngine.Execute(MacroModel macro, INode currentPage)
  • Michael Latouche 504 posts 819 karma points MVP 4x c-trib
    Apr 14, 2011 @ 13:28
    Michael Latouche
    0

    Hi Lennart,

    Hard to say... If you are working with datatypes and properties you defined yourself, you should normally have full control on the actual type, so if you want strings, you should be able to get strings. But maybe you are working with a 3rd party package/library, where the scores might then have been defined as DateTime, and then your property ParticipantScore has to be defined as datetimr? Maybe you can give some more info about the datatype/properties?

    Or, now that I just think of it: you are doing order by on "participantScore", not "ParticipantScore". Case-sensitivity issue?

    Cheers,

    Michael.

  • Lennart Stoop 304 posts 842 karma points
    Apr 14, 2011 @ 13:49
    Lennart Stoop
    0

    @Michael: Nope, its actually a very basic setup, with self-defined document types and properties. The ParticipantScore is a property on the Highscore document type, and its datatype is a Textstring. I've also looked into the database and its db type is NVarchar so I really don't see an issue with the setup.

    Its kinda funny because when I update the actual scores in the Content tree and replace the colons by dashes for example, I get about the same error: "Object must be of type String" instead of "Object must be of type DateTime".

    So the type is dynamic and there seems to be something odd going on with how it is selected at runtime.

  • Lennart Stoop 304 posts 842 karma points
    Apr 14, 2011 @ 13:51
    Lennart Stoop
    0

    Ah, and case sensitivity does not seem to be an issue either, thanks though :-)

  • Michael Latouche 504 posts 819 karma points MVP 4x c-trib
    Apr 14, 2011 @ 15:20
    Michael Latouche
    0

    Mmh,

    So I guess razor is doing some kind of implicit typing ... Sorry but I can't help you much further on razor :-S

    I hope some of the razor guru's will catch up the conversation and help you further...

    Cheers,

    Michael.

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Apr 16, 2011 @ 13:55
    Sebastiaan Janssen
    0

    The Razor implementation in Umbraco tries to do ducktyping on your property values. To circumvent that, use this instead:

    var myTimespan = @highscore.GetProperty("participantScore").Value;

    Make sure the casing in "participantScore" is the same as the alias of your property.

    This will return the value as a string and you could throw it into a TimeSpan object, which seems to be what you want (as opposed to a DateTime object).

    To make the ordering work, I think you could propbably do: "participantScore.ToString()" to stop it from being cast as a DateTime object.

  • Lennart Stoop 304 posts 842 karma points
    Apr 16, 2011 @ 15:12
    Lennart Stoop
    0

    Hi Sebastiaan,

    Thanks for your reply.

    Using GetProperty("participantScore").Value indeed allows me to retrieve the value as a string and convert it into a TimeSpan object, perfect!

    The expression "participantScore.ToString()" also works for sorting, although I just realized that sorting these values as strings is not really a great approach (as for example the value "08:10" is treated to be larger than "10:05" when working with strings).

    Seeing that ToString() works within the expression, I was hoping to quickly fix this by throwing in an extension method that would convert the string values into Timespan objects:

        public static class StringExtensions
        {
            public static TimeSpan ToTimeSpan(this string text)
            {
                return TimeSpan.Parse(text);
            }
        }

    After changing the sorting expression to "participantScore.ToString().ToTimespan()" I'm hitting the following LINQ exception:

    Error Loading Razor Script (file: Highscores) Expression of type 'System.Object' cannot be used for label of type 'System.TimeSpan'    at System.Linq.Expressions.Expression.ValidateGotoType(Type expectedType, Expression& value, String paramName)
      at System.Linq.Expressions.Expression.Label(LabelTarget target, Expression defaultValue)
      at System.Linq.Dynamic.ExpressionParser.CallMethodOnDynamicNode(Expression instance, Expression[] args, LambdaExpression instanceAsString, ParameterExpression instanceExpression, MethodInfo method, Boolean isStatic)

    Any ideas?

Please Sign in or register to post replies

Write your reply to:

Draft