5

I generate an XML/Google sitemap on the fly using an Http Handler, so that I don't need to maintain an XML file manually.

I have mapped my Http Handler to "sitemap.xml" in my web.config like this:

<httpHandlers>
  <add verb="*" path="sitemap.xml" type="My.Name.Space, MyAssembly" />
</httpHandlers>

It works nicely. Now, www.mywebsite.com/sitemap.xml sets my Http Handler into action and does exactly what I want. However, this url will do the same: www.mywebsite.com/some/folder/sitemap.xml and I don't really want that i.e. I just want to map my handler to the root of my application.

I have tried changing the "path" of my handler in my web.config to "/sitemap.xml" and "~/sitemap.xml" but neither works.

Am I missing something here?

alexandrul
  • 12,856
  • 13
  • 72
  • 99
Alex York
  • 5,392
  • 3
  • 31
  • 27

4 Answers4

5

Try adding the following to your web.config

<urlMappings enabled="true">
    <add url="~/SiteMap.xml" mappedUrl="~/MyHandler.ashx"/>
</urlMappings>

This uses a little known feature of ASP.NET 2.0 called 'Url Mapping'

Ali Kazmi
  • 3,610
  • 6
  • 35
  • 51
  • That's more like what I'm after, but now it requires a physical .ashx file and at the moment I don't have that - just a class implementing IHttpHandler, no physical file in my web project. I will use this method IF there are no better suggestions... – Alex York Apr 01 '09 at 07:44
  • 2
    You can just create a ashx file in you web application pointing to your handler in another assembly like this: <%@ WebHandler Language="C#" Class="MyHandlersNamespace.MyHandler, MyHandler" %> Here I refer to a handler in another assembly called 'MyHandlers' – Ali Kazmi Apr 01 '09 at 08:41
1

Following on from Kirtan suggested solution #1 you can do a workaround like follows:

public void ProcessRequest(HttpContext context) {
  //Ensure that the sitemap.xml request is to the root of the application
  if (!context.Request.PhysicalPath.Equals(Server.MapPath("~/sitemap.xml"))) {
     //Invoke the Default Handler for this Request
     context.RemapHandler(null);
  }

  //Generate the Sitemap
}

You might need to play with this a bit, not sure if invoking the default handler will just cause IIS to re-invoke your Handler again. Probably worth testing in Debug mode from VS. If it does just re-invoke then you'll need to try invoking some static file Handler instead or you could just issue a HTTP 404 yourself eg

//Issue a HTTP 404
context.Response.Clear();
context.Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return;

See the MSDN documentation on HttpContext.RemapHandler for more info - http://msdn.microsoft.com/en-us/library/system.web.httpcontext.remaphandler.aspx

RobV
  • 28,022
  • 11
  • 77
  • 119
  • Had a go at this and ended up issuing the 404 myself as suggested above. Handler's code still gets run but only if a page that doesn't exist is requested. – tentonipete Feb 09 '12 at 14:33
0

You can, alternately, run a check in the global.asax, verify the request, and finaly re-assigning a new handler throughtout context.RemapHandler method.
The only thing is that you would´ve to implement a factory for that matter.

I would suggest you inherit the HttpApplication, and implement there the factory, but that's your call.

marcelo-ferraz
  • 3,147
  • 4
  • 38
  • 55
0

2 solutions to this:

Soln #1: You can check the request path using the Request.Url property, if the request is from the root path, you can generate the XML, else don't do anything.

Soln #2: Put a web.config file with the following setting in every folder in which you don't want to handle the request for the sitemap.xml file.

Kirtan
  • 21,295
  • 6
  • 46
  • 61
  • Solution 1 still means by handler's code gets run. I don't want that. I want to only run it when a specific URL (the root) gets requested. Admittedly, this is my fallback. Solution 2 isn't really an option: putting a web.config in every directory! What if I have hundreds of directories? – Alex York Apr 01 '09 at 07:26