views:

322

answers:

1

This extension method does not work on two separate development machines:

public static string DdlTest(this HtmlHelper helper)
{
    var si = new List<SelectListItem>();
    si.Add(new SelectListItem() { Text = "1", Value = "1" });
    si.Add(new SelectListItem() { Text = "2", Value = "2" });
    return helper.DropDownList("test", si, new { Class = "Hey" });
}

I get the following error:

Method not found: 'System.String System.Web.Mvc.Html.SelectExtensions.DropDownList(System.Web.Mvc.HtmlHelper, System.String, System.Collections.Generic.IEnumerable`1, System.Object)'.

However, this in-line code does work:

<%
    var si = new List<SelectListItem>();
    si.Add(new SelectListItem() { Text = "1", Value = "1" });
    si.Add(new SelectListItem() { Text = "2", Value = "2" });
%>
<%= Html.DropDownList("test", si, new { Class = "Hey" })%>

Could someone please verify I'm not going crazy!

Please be aware:

It does work in VS2010 and .NET 4 beta 2.

It does work in VS2010 with MVC 2 beta.

It does not work in VS2008 with MVC 1!!

On both machines I have VS2010 beta 2 and VS2008 installed side-by-side.

Am I doing something wrong here?

Edit:

For now I've hacked this by disassembling the SelectExtensions class and implementing it myself, which works. Interestingly, in the disassembled code there was an ambiguous method call error.. not sure if this is just the result of reflection though.

Edit 2:

To make the example clearer, suppose this ASPX:

<%
    var si = new List<SelectListItem>();
    si.Add(new SelectListItem() { Text = "1", Value = "1" });
    si.Add(new SelectListItem() { Text = "2", Value = "2" });
%>
<%= Html.DropDownList("test", si, new { Class = "Hey" })%>
<%= Html.TextBox("testing")%>
<%= Html.DdlTest1("test", si, new { Class = "Hey" })%>
<%= Html.DdlTest2("test", si, new { Class = "Hey" })%>
<%= Html.Test3()%>

And this in my extension methods class:

using System.Web.Mvc;
using System.Web.Mvc.Html;

...

public static string DdlTest1(this HtmlHelper helper, string name,
    IEnumerable<SelectListItem> items, object htmlAttributes)
{
    return "Whatever";
}

public static string DdlTest2(this HtmlHelper helper, string name,
    IEnumerable<SelectListItem> items, object htmlAttributes)
{
    return helper.DropDownList(name, items, htmlAttributes);
}

public static string Test3(this HtmlHelper helper)
{
    return helper.TextBox("testing");
}

<%= Html.DropDownList("test", si, new { Class = "Hey" })%> will work
<%= Html.TextBox("testBox")%> will work <%= Html.DdlTest1() %> will work
<%= Html.DdlTest2() %> will give the following error:

Method not found: 'System.String System.Web.Mvc.Html.SelectExtensions.DropDownList(System.Web.Mvc.HtmlHelper, System.String, System.Collections.Generic.IEnumerable`1, System.Object)'.

<%= Html.DdlTest3() %> will give the following error:

Method not found: 'System.String System.Web.Mvc.Html.InputExtensions.TextBox(System.Web.Mvc.HtmlHelper, System.String)'.

So we can conclude that the ASPX can find my extension methods, and even the normal .NET ones. But when my extensions, in MVC 1, try to call the standard extensions, trouble brews!

Edit 3:

Sigh.

I found the problem, and I suppose in many ways Aaronaught buddy you were right!

I did have the assembly reference in my Web.Config, but I'd missed one tiny detail:

<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

It really should have read:

<add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

I didn't spot that evil, b*stard 2 in there. I'm sorry peeps, thanks for all your help. Points go to you Aaronaught as you were right after all!

+2  A: 

So clearly my first answer wasn't related to the problem... but I'm wondering if it's something else configuration-related. In your web.config you should have this in your <assemblies>:

<add assembly="System.Web.Mvc, Version=1.0.0.0, Culture=neutral,
     PublicKeyToken=31BF3856AD364E35"/>

My next hunch is that you might have either the wrong version or no entry at all, which could be causing it to pick up the MVC 2.0 version from somewhere (GAC perhaps). The application might be trying to call the extension method from MVC 2.0, but passing it an HtmlHelper object compiled against MVC 1.0, which would get you that nonsensical error message.

In other words maybe it found the method just fine but in the wrong assembly, so the HtmlHelper you need isn't actually the same HtmlHelper it wants. The method signatures look identical but aren't quite identical.

Can you check both your web.config and your Project References in VS2008 and make sure that the version of System.Web.Mvc is the same in both?

Aaronaught
You're confusing the two a little - as the error suggests (hehe) it is the original `DropDownList` extension method that it's having trouble finding. All the right assemblies and namespaces are in the Web.Config anyway (for my extensions). Other extensions methods of my own work perfectly fine :(
joshcomley
@josh: I noticed that afterward, but it's a little confusing because you don't specify at what point you get this error (see my comment to the original question). I'm definitely able to write this in VS 2008, MVC 1, and it compiles and runs.
Aaronaught
@Aaronaught - fair enough, my question was confusing! I've edited my question (see: **Edit 2**) outlining a simple example of it getting its knickers in a right old twist. I'm glad you've confirmed that it works, thanks for that.
joshcomley
@Aaronaught - You win!
joshcomley