1

I've written a custom HTTP module for a C# ASP.Net app which is deployed to IIS 7.5 running locally. My client sends POST requests to a URL like "http://localhost:9999". I can see my custom module is being executed and is returning the correct response inside the event handler that I registered in my custom module's Init() method. However the actual HTTP response being returned to my client has this in its header:

HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS, TRACE

Annoyingly I can see the response I expect in the body of the HTTP response, but the header tells the client 405 Method Not Allowed and so the client call fails! Does anyone know how to stop this error please?

Here's the relevant part of my app's web.config:

  <system.webServer>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0"
           path="*."
           verb="*"
           type="System.Web.Handlers.TransferRequestHandler"
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules>
       <remove name="WebDAVModule"/>
       <add name="AuthServiceModule" type="AuthServiceHTTPModule.App_Code.AuthServiceModule"/>       
    </modules>
  </system.webServer>

where AuthServiceModule is the name of my custom module. I've tried many different options inside the system.webServer element but none seem to allow the POST request through. I'd rather have a solution that involves config within the app rather than IIS itself, please.

snark
  • 2,462
  • 3
  • 32
  • 63

1 Answers1

1

Since you have not explicitly mentioned, I assume this is not for MVC.

Modules are part of the processing that happens during the request execution, but that is not at the end of the http pipeline See Here. (And here where it's said nicely that HttpHandler is where the request train is headed. HttpModule is a station along the way.) What it means is that when a request is received at the asp.net side, it goes through all the modules and expects an handler to act on the request. When you process the request in handler and determines main response, response starts traversing back through all the modules, and then sent back to client.

In your case above, looks like you have created an http module but missing a handler. Unless there is a reason for creating a module i.e. some request level event you want to tackle, I would suggest you would have to create an HTTP Handler and process the request inside the handler. That should help you process it successfully.

Something like this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MyWorld
{
public class HelloWorldHandler : IHttpHandler
{
    public HelloWorldHandler()
    {
    }
    public void ProcessRequest(HttpContext context)
    {
        HttpRequest Request = context.Request;
        HttpResponse Response = context.Response;

        Response.Write("<html>");
        Response.Write("<body>");
        Response.Write("<h1>Hello from a synchronous custom HTTP handler.</h1>");
        Response.Write("</body>");
        Response.Write("</html>");
    }
    public bool IsReusable
    {
        // To enable pooling, return true here.
        // This keeps the handler in memory.
        get { return false; }
    }
}
}

And in the web.config then you register

 <handlers>
  <remove name="WebDAV" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0"
       path="*."
       verb="*"
       type="MyWorld.HelloWorldHandler"
       preCondition="integratedMode,runtimeVersionv4.0" />    
</handlers>
Community
  • 1
  • 1
Subhash Dike
  • 1,836
  • 1
  • 22
  • 37
  • Thanks for the suggestion. No, this is not MVC as far as I know. But do I _have_ to use a handler? If I did then I wouldn't need the module at all. I already know the module works; it's just the framework that's causing the 405 error. Also, a module seems more appropriate in my case as I want it to run on _all_ requests; and also my requests have no extension or even requested resource anyway. (I actually use the module to call an Apache Thrift processor as I'm using Thrift/HTTP.) – snark Mar 09 '16 at 15:07
  • @snark , the above sample I have shown is for non-mvc (regular asp.net web apps work) and it would work fine. As I said above, module is meant for handling the request workflow, but the request has to be served by handler in the end. As you see above sample, the handler is also extension less, and it would also get execute on all extensionless request. What you can also do is , put the logic in module so that it gets executed on all requets and let handler handle the request for anything else. – Subhash Dike Mar 09 '16 at 16:09
  • Well, as I couldn't get the module approach to work I tried the handler instead, and... it worked! My working web.config looks the same as yours (apart from the `name` and `type` attribute values for the `add` element), and I also had this child under the `system.webServer` element: ``. So thanks for the suggestion, and I've upvoted your answer. But I'm still leaving the OP unanswered because I bet it's still possible to get the module-only approach working without having to add any more handlers that aren't already in IIS. – snark Mar 11 '16 at 10:07
  • If you're interested you can see more details about the handler at http://stackoverflow.com/a/35938562/1843329 – snark Mar 11 '16 at 11:10