Copied to clipboard

Flag this post as spam?

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


  • Asbjørn 82 posts 195 karma points c-trib
    Jun 19, 2011 @ 16:56
    Asbjørn
    0

    Razor extension methods

    I'm evaluating Razor im Umbraco 4.7 for upgrading an existing site from 4.5. I want to rewrite some macros in Razor, if it works, that is. I'm currently testing extensions methods and I have run into a problem. As stated in this blog post (http://umbraco.com/follow-us/blog-archive/2011/2/28/umbraco-razor-feature-walkthrough-%E2%80%93-part-3), all you have to do is put this in a class library and put it in the /bin folder. That, unfortunately, does not work for me (not even the provided sample code). Has something changed since this blog post was written (it seems to be pretty much the only documentation around for this)?

    The site in question is unfortunately confidential, so I cannot really show much code. I will have to make a reduced testcase first (which in any case might be a good idea!)

  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Jun 20, 2011 @ 22:30
    Dan Diplo
    2

    Hi,

    I've written extension methods for Umbraco 4.7 based on that blog-post and they work fine. Remember that your extension methods MUST go in a static class and you may need to import the namespace. One easy way to use extension methods is to simply place your code in the App_Code folder (at least whilst developing). For instance, here's an entire example of an extension method class I've put in App_Code called RazorExtensions.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using umbraco.MacroEngines;

    namespace Diplo
    {
    public static class RazorExtensions
    {
    public static DynamicNodeList TopNodesByDate(this DynamicNodeList nodes, int amount)
    {
    return new DynamicNodeList(nodes.Items.OrderBy(d => d.CreateDate).Take(amount));
    }
    }
    }
     

    And now here's an example of it in use:

    <ul>
    @foreach (var item in Model.Children.TopNodesByDate(3))
    {
    <li><a href="@item.Url">@item.Name</a></li>
    }
    </ul>
     
  • Sebastiaan Janssen 5044 posts 15475 karma points MVP admin hq
    Jun 23, 2011 @ 09:45
    Sebastiaan Janssen
    0

    Good explanation Dan, works for me! Don't actually need the namespace and some of the usings:

    using System.Linq;
    using umbraco.MacroEngines;

    public static class RazorExtensions
    {
        public static DynamicNodeList TopNodesByDate(this DynamicNodeList nodes, int amount)
        {
            return new DynamicNodeList(nodes.Items.OrderBy(d => d.CreateDate).Take(amount));
        }
    }
  • Dan Diplo 1554 posts 6205 karma points MVP 5x c-trib
    Jun 23, 2011 @ 18:24
    Dan Diplo
    0

    Thanks, Seb. True, you don't need those namespaces but Visual Studio likes to add them and who am I to argue with M$? :)

  • Sean Dooley 288 posts 527 karma points
    Jul 14, 2011 @ 12:33
    Sean Dooley
    0

    I'm experiencing the same issue. I have placed the following in the project App_Code folder

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using umbraco.MacroEngines;
    
    namespace Dool {
      public static class RazorExtensions {
        public static bool ContainsAny(this string haystack, List needles) {
          if (!string.IsNullOrEmpty(haystack) || needles.Count > 0) {
            foreach (string value in needles) {
              if (haystack.Contains(value)) { return true; }
            }
          }
          return false;
        }
      }
    }
    

    And below is my Razor script

    @inherits umbraco.MacroEngines.DynamicNodeContext
    
    @using uComponents.Core
    @using uComponents.Core.uQueryExtensions
    @using System.Linq
    
    @{
      var rootNode = uQuery.GetRootNode();
      var searchString = HttpContext.Current.Request.QueryString["SearchTerm"];
      var keywords = HttpContext.Current.Request.QueryString["SearchTerm"].Split(' ').ToList();
      var values = new Dictionary();
      values.Add("keywords", keywords);
      var pagesToList = rootNode.GetDescendantNodes().Where(x =>
        x.Name.ToLower().Contains(searchString) ||
        x.GetPropertyAsString("bodyText").ToLower().ContainsAny(keywords)
    );
    ...
    

    And this is the error that is appearing.

     'string' does not contain a definition for 'ContainsAny' and no extension method 'ContainsAny' accepting a first argument of type 'string' could be found

    The Umbraco example, calls ContainsAny like follows

    var items = @Model.Children.Where("Name.ContainsAny(keywords)", values); 

    Any ideas on how I correctly call ContainsAny with the syntax that I am using?

  • Scott Williams 14 posts 71 karma points
    Jul 14, 2011 @ 13:14
    Scott Williams
    0

    you will need to add (for your example extension method)

    @using Dool

    to your razor file, you need to register the namespace to your extension method class for c# to be able to see it and run the method, thi goes for normal classes to.

  • Sean Dooley 288 posts 527 karma points
    Jul 14, 2011 @ 13:25
    Sean Dooley
    0

    Thanks Scott Williams - exact answer I was looking for

Please Sign in or register to post replies

Write your reply to:

Draft