Sergio Tapia
Sergio Tapia

Reputation: 41208

My extension method isn't registering (Error 1 'System.Web.Mvc.HtmlHelper' does not contain a definition for 'PageLinks' and ...)

I'm following Pro ASP.Net MVC2 book and literally 90% of everything is new to me. I feel like a kid in a candy store! :)

Unit testing, dependency injection, and other things are really new and very foreign to the typical CRUD applications I create.

Now I'm having trouble with a test the book asks us to design.

[Test]
        public void Can_Generate_Links_To_Other_Pages()
        {
            // Arrange: We're going to extend the HtmlHelper class.
            // It doesn't matter if the variable we use is null.
            HtmlHelper html = null;

            // Arrange: The helper should take a PagingInfo instance (that's
            // a class we haven't yet defined) and a lambda to specify the URLs
            PagingInfo pagingInfo = new PagingInfo
            {
                CurrentPage = 2,
                TotalItems = 28,
                ItemsPerPage = 10
            };
            
            Func<int, string> pageUrl = i => "Page" + i;

            // Act
            MvcHtmlString result = html.PageLinks(pagingInfo, pageUrl);

            // Assert: Here's how it should format the links
            result.ToString().ShouldEqual(@"<a href=""Page1"">1</a>
                                            <a class=""selected"" href=""Page2"">2</a>
                                            <a href=""Page3"">3</a>");
        }

My html variable is a HtmlHelper variable. It seems that the extension method PageLinks() isn't correctly registered.

Where would I check for this?

Edit

Apparently this is where I registered the extension method. Although it doesn't seem to extend anything. At least IntelliSense doesn't show it when I type it in the above code.

public static class PagingHelpers
    {
        public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func<int, string> pageUrl)
        {
            StringBuilder result = new StringBuilder();

            for (int i = 1; i <= pagingInfo.TotalPages; i++)
            {
                TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag
                tag.MergeAttribute("href", pageUrl(i));
                tag.InnerHtml = i.ToString();
                if (i == pagingInfo.CurrentPage)
                    tag.AddCssClass("selected");
                result.AppendLine(tag.ToString());
            }

            return MvcHtmlString.Create(result.ToString());         
        }
    }

Also, how can I set up Visual Studio so it just copies plain text without its ridiculous indentation?

Edit 2

Woops! Forgot to type in the error:

Error 1 'System.Web.Mvc.HtmlHelper' does not contain a definition for 'PageLinks' and no extension method 'PageLinks' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference?) C:\Users\Sergio\documents\visual studio 2010\Projects\SportsStore\SportsStore.UnitTests\DisplayingPageLinks.cs 35 41 SportsStore.UnitTests

Upvotes: 3

Views: 2445

Answers (5)

Rellaxx
Rellaxx

Reputation: 21

You can remove this HtmlHelper html, from parameters of PageLinks method code in PagingHelpers class, and replace HtmlHelper with PagingHelpers like this MvcHtmlString result = PagingHelpers.PageLinks(pagingInfo, pageUrl);

HtmlHelper is not used in your example.

Upvotes: 0

Killuminati
Killuminati

Reputation: 271

You need to add in your List.cshtml above the code this line

@model SportsStore.WebUI.Models.ProductsListViewModel

Upvotes: 0

Erik
Erik

Reputation: 1

Use

MvcHtmlString result = PagingHelpers.PageLinks(myHelper, pagingInfo, pageUrlDelegate);

instead of

MvcHtmlString result = myHelper.PageLinks(pagingInfo, pageUrlDelegate);

Upvotes: 0

odyth
odyth

Reputation: 4336

You can add the namespace to all your pages in the web.config like this:

<system.web>
 <pages>
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Routing" />
    <add namespace="System.Linq"/>
    <add namespace="System.Collections.Generic"/>
    <add namespace="YourNameSpace.HtmlHelpers"/>
  </namespaces>
</pages>

Upvotes: 3

Rex M
Rex M

Reputation: 144162

To use an extension method, you need to include the namespace in which the extension method class resides. You also need to ensure the extension method class is static and accessible to consuming code (e.g. can't be internal if it's in another assembly). Finally, be sure not to forget the this keyword on the type you're extending. If all those things are in place, you shouldn't see a problem.

Upvotes: 8

Related Questions