views:

1242

answers:

3

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?

A: 

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
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
+4  A: 

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
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
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
A: 

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