Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Ambiguous References in DefaultWsdlHelpGenerator.aspx


:P
On this page:

Here’s a little oddball issue I ran into today that hosed – during a demo of course – all the existing ASMX Web Services text pages in one of my applications. The error that occurred resulted in a yellow screen of death when accessing the ASMX service directly (http://localhost/wwstore/services/WebStoreConsumerService.asmx):

CS0104: 'DataBinder' is an ambiguous reference between 'Westwind.Web.Controls.DataBinder' and 'System.Web.UI.DataBinder'

WsdlPageerror

The issue here is caused by the fact that I have  a component in Westwind.Web.Controls.DataBinder that apparently conflicts with the System.Web.UI.DataBinder. You would think that the separate namespaces should isolate me from problems like this, but unfortunately here the overlapping names ram heads due to the use of a static method call of DataBinder.Eval().

The problem is that the DataBinder.Eval() is a static method call so there’s never an instance created to qualify exactly which type is to be used. Both System.Web.UI and Westwind.Web.Controls are in scope, the former because it’s automatically included as a namespace, the latter because it’s added explicitly in the <pages><namespaces> section of Web.Config:

    <pages>
      <namespaces>
        <add namespace="Westwind.Web" />
        <add namespace="Westwind.Web.Controls" />
        <add namespace="Westwind.Utilities" />
        <add namespace="Westwind.WebStore" />
      </namespaces>
      <controls>
        <add assembly="Westwind.Web" namespace="Westwind.Web.Controls" tagPrefix="ww" />
      </controls>
    </pages>

which automatically includes the namespace into the page.

The result is that that the DataBinder.Eval() can’t be resolved properly by the compiler – it doesn’t know which DataBinder should be used. Actually it’d be nice if the compiler was smart enough to check for the actual method Eval before throwing the error. Since my component doesn’t have a static Eval method (or any static members for that matter) it seems that the compiler should be able to prioritize the call.

Ironically this error would not be an issue if this was anything but a framework provided page which is:

C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\DefaultWsdlHelpGenerator.aspx

To fix the problem is easy enough by changing all the .NET 1.x DataBinder.Eval() calls with:

<%# System.Web.UI.DataBinder.Eval(Container.DataItem, "Value.Documentation") %>    

or

<%# Eval("Value.Documentation") %>    

Replacing all DataBinder.Eval instances with either code fixes the problem, but of course it only does so on my machine(s) – still a problem for anybody else.

In the end there are few solutions that can be used to work around this problem – none really satisfying. The easiest and the one I actually ended up with is by removing the Westwind.Web.Controls namespace from the global ASP.NET namespace list:

      <namespaces>
        <add namespace="Westwind.Web" />
        <!--<add namespace="Westwind.Web.Controls" />-->
        <add namespace="Westwind.Utilities" />
        <add namespace="Westwind.WebStore" />
      </namespaces>

It turns out that this works just fine in my case because the Westwind.Web.Controls namespace isn’t used much in Web page code. A while back I thankfully refactored all the utility and control code into separate namespaces, so the need for the Controls namespace is not used much if at all.

The other option I was at first considering to get around this was to put the control into a separate namespace (ie. Westwind.Web.Controls.DataBinding) which certainly would have worked but this causes a number of problems when adding page register commands into the page. The following wouldn’t work:

<%@ Register Assembly="Westwind.Web" Namespace="Westwind.Web.Controls" TagPrefix="ww" %>

unless I also add:

<%@ Register Assembly="Westwind.Web" Namespace="Westwind.Web.Controls.DataBinding" TagPrefix="ww" %>

IOW, changing a lot of pages potentially.

Finally another solution is to add web.config file into the folder with the Web Service(s) and explicitly exclude the offending namespace(s):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <pages>
      <namespaces>        
        <remove namespace="Westwind.Web.Controls"/>
      </namespaces>
    </pages>
  </system.web>
</configuration>

This assumes you isolate the Web Services into a separate folder.

This is obviously a very isolated incident and situation, but it’s easy to get tripped up by this. Ideally I think that the generic .NET code in DefaultWsdlHelpGenerator.aspx was namespace safe by explicitly prefixing namespaces in static method calls.

There goes another couple of hours of sleuthing to find a solution. <shrug>

Posted in ASP.NET  Web Services  

The Voices of Reason


 

Andy Miller
November 02, 2009

# re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

Would a location element work? Then the service does not need to be in a separate directory.

<configuration>
  <location path="mywebservice.asmx">
    <system.web>
      <pages>
        <namespaces>        
          <remove namespace="Westwind.Web.Controls"/>
        </namespaces>
      </pages>
    </system.web>
  </location>
</configuration>

Rick Strahl
November 03, 2009

# re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

@Andy - yes that should work too. Problem is I typically have a few services (hmmm *.asmx might work in that case - can't remember if wildcards work in location tag).

Richard Deeming
November 03, 2009

# re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

You could always replace the default documentation page with your own version:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <webServices>
            <wsdlHelpGenerator href="wsdlDocumentation.aspx" />
        </webServices>
    </system.web>
</configuration>


The value of href is a file path. The file path can be relative or absolute. If it is relative, it is relative to the location of the configuration file.
http://msdn.microsoft.com/en-us/library/ycx1yf7k%28VS.85%29.aspx

Matt Slay
November 04, 2009

# re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

This is not so isolated as you may think... I ran into the same problem just building a regular aspx page on my simple CRUD app that I've been working on.

I used this solution, which you showed in your post:
<%# System.Web.UI.DataBinder.Eval(Container.DataItem, "Value.Documentation") %>

Peter Crabtree
January 17, 2012

# re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

FYI, at least as of .Net 4, having been bitten by this today, this does not work:

<location path="mywebservice.asmx">


(Nor does putting a web.config in the relevant directory.)

You have to use this:

<location path="DefaultWsdlHelpGenerator.aspx">


So for the example above, you'd use:

<configuration>
  <location path="DefaultWsdlHelpGenerator.aspx">
    <system.web>
      <pages>
        <namespaces>        
          <remove namespace="Westwind.Web.Controls"/>
        </namespaces>
      </pages>
    </system.web>
  </location>
</configuration>

On the plus side, this fixes the issue for all of your web services.

Rob
October 12, 2012

# re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

I know this thread is old, but this was mucho helpful patching a legacy app. Thanks! The previous comment put it together nicely as well.
 

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2019