views:

1763

answers:

5

Hi,

I have written an ASP.NET composite control which includes some Javascript which communicates with a web service.

I have packaged the classes for the control and the service into a DLL to make it nice and easy for people to use it in other projects.

The problem I'm having is that as well as referencing the DLL in their project, the consumer of my control must also include a .ASMX file for the web service. Whilst it isn't a complicated file (just a one-liner which refers to the class in the DLL), I would like to avoid having it if I can.

Is there any way to avoid having to have the .ASMX file?

  • Can I register the service with the web server in Application_Start?
  • Can I make a web.config change to reference it somehow?

All suggestions gratefully received!

UPDATE: The article linked to in John Sheehan's response (below) does work - but not if you want to call the web service using AJAX. Does anybody know of an AJAX friendly version?

A: 

Short answer is no. The ASMX is the entry point for any web service. There are alternatives if you use WCF, but that's not entirely the same thing.

Chris
Sorry you didn't like the answer, but it IS the answer.
Chris
Except for its not. You can put web services in a class library and wire them up with the web.config.
John Sheehan
Except it is. I said the *short* answer is no. And you cannot host a regular web service without the .asmx file. The article to which you link surely describes a work around, but it is non-standard, and quite a verbose (as in, not short) solution.
Chris
Actually, the article is quite short and easy to implement. I think the total amount of code not including white space is < 10 lines. How is that "long"? I also fail to see how it's non-standard. It does not make use of any hidden APIs, it invokes no warnings from Microsoft. It's quite simple and I am now using it quite successfully.
ryber
Indeed Microsoft often has what I call the "non-programmer" way and programmer way of doing the same thing. Often the former involves GUI and/or drag-a-drop so they can market the technology to the masses as "easy to implement!" (like an empty, redundant ASMX file in the source tree). Of course the latter way is often not focused on as much. But for sure, don't mix it up with "non-standard" or think the pure programming way is wrong or complex.
John K
+4  A: 

Try something like this. I don't know if it will work though. I got this idea from ELMAH, which creates a handler for a page that doesn't physically exist and then serves it up from the assembly.

<configuration>
   <system.web>
      <httpHandlers>
         <add verb="*" path="*WebService.asmx" type="MyHandler.WebServiceHandler, MyHandler" />
      </httpHandlers>
   </system.web>
</configuration>

EDIT: I was close, see this article (in VB though): http://www.codeproject.com/KB/aspnet/wsinaclasslibrary.aspx

John Sheehan
Perfect, been looking for this for a long time
ryber
A: 

Consider trying page methods (see this blog post). All you have to do is add the web method attribute to a static method in the aspx code behind. Then access the PageMethod object from your clientside code (javascript). No ASMX files needed. Hope this helps.

Darwyn
A: 

I know this is very old question, but it hasn't been answered properly, so here it is:

Every *.ASMX request is by default handled by System.Web.Services.Protocols.WebServiceHandlerFactory.

Looking into source code of this class in .NET reflector, it's possible to have webservice without ASMX file but you will need to call internal method CoreGetHandler through reflection.

Following method will take your webservice and return its IHttpHandler.

public IHttpHandler GetHttpHandlerForWebService(WebService webService, HttpContext context)
{
    var webServiceType = webService.GetType();
    var wshf = new System.Web.Services.Protocols.WebServiceHandlerFactory();
    var coreGetHandler = wshf.GetType().GetMethod("CoreGetHandler");
    var httpHandler = (IHttpHandler)coreGetHandler.Invoke(wshf, new object[] { webServiceType, context, context.Request, context.Response });
    return httpHandler;
}

Once you have your httphandler, it's just matter of calling

httpHandler.ProcessRequest(context)

Done. No ASMX and no web.config entries.

lubos hasko
Can you explain where this code would go? Your client code needs to have an accessible URL. If there is no ASMX placeholder or httpHandler defined in web.config, what is the entrypoint URL?
Nelson
This method (specifying an httpHandler in web.config) works well for the most part, but the `[System.Web.Script.Services.ScriptService]` attribute seems to be ignored. JSON sent to the server throws an exception (invalid format) and `MyService.asmx/js` or `MyService.asmx/jsdebug` return a 500 (in IE) or 401 authentication failed error. With a placeholder .asmx, these problems go away.
Nelson
@nelson, if you have IIS in integrated mode, all http requests go through ASP.NET engine (even without web.config or asmx placeholder files). so basically what you need to do is to override one of the asp.net life-cycle methods such as `Init` and inject your httpHandler by calling `httpHandler.ProcessRequest(context)`. Obviously you will need to have variable `httpHandler` already set. that's why I provided method that will convert your webservice class into generic `IHttpHandler`.
lubos hasko
A: 

AJAX friendly version:

http://www.codeproject.com/KB/cpp/WebserviceAndJavaProxy.aspx

Luc
(nothing against you, the link is now 404)
Luk