tags:

views:

361

answers:

2

I am implementing a dynamic ASMX web service via a custom HttpHandler, and my web service has recently stopped generating WSDL automatically. When I use ?WSDL on the asmx url, I get the following error:

System.InvalidOperationException: XML Web service description was not found.
   at System.Web.Services.Protocols.DiscoveryServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
   at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
   at System.Web.Services.Protocols.WebServiceHandler.Invoke()

This worked fine a while ago, so I'm wondering if there's a file permission problem somewhere.

A Google search does not return any reference to this particular situation.

I doubt that my code is relevant to the problem; it has not changed:

[WebService(Description = "...", Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class MyWebService : System.Web.Services.WebService
{
    [WebMethod]
    void MyWebMethod() {}
}

public class VirtualWebServiceFactory : IHttpHandlerFactory
{
    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
    {
        WebServiceHandlerFactory wshf = new WebServiceHandlerFactory();
        MethodInfo coreGetHandler = wshf.GetType().GetMethod("CoreGetHandler", BindingFlags.NonPublic | BindingFlags.Instance);
        IHttpHandler handler = (IHttpHandler)coreGetHandler.Invoke(wshf, new object[] { typeof(MyWebService), context, context.Request, context.Response });    
        return handler;
    }
}

Decompiling System.Web.Services.Protocols.DiscoveryServerProtocol.WriteReturns() reveals that it looks up the XML service description in a dictionary created somewhere else.

I was hoping that someone familiar with the DiscoverServerProtocol etc. might know under what circumstances the XML service description might fail to be built.

The following works just fine:

ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
reflector.Reflect(typeof(MyWebService), "...");

Navigating to MyWebService.asmx shows all the functions and allows testing them. But using ?WSDL gives the exception above.

A: 

Just for fun, try making your WebMethod public.

However, the real answer is to not screw around with .NET Framework code that's not meant to be called. What's wrong with just calling GetHandler? What are you trying to accomplish here that can't be accomplished without messing around in the internals of an obscure class?

John Saunders
Notice the difference in the parameters of GetHandler() and CoreGetHandler().CoreGetHandler() returns a handler that provides the default page that lists the web service methods and (until recently) the WSDL.The task I'm trying to accomplish is to provide a virtual web service without a physical .asmx file.
Gordon Tisher
Again, I wouldn't be playing around with legacy technology (ASMX) and expecting to get anything done. Move to WCF, which has a real extensibility architecture, that doesn't require you to use Reflection to call undocumented internal methods.
John Saunders
Unfortunately I am working on a large legacy code base, with little chance of moving to WCF anytime soon.
Gordon Tisher
Is there some article or blog post that led you to believe this could work? Also, without hacking .NET, you can replace the page that displays the help, just in the web.config.
John Saunders
A: 

Hmm, after many months, found out that the URL was being re-written to include other parameters than the ?WSDL, which made the private function choke.

Gordon Tisher