Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Nested Item Templates for custom script extensions in Visual Studio


:P
On this page:

I'm working on an application that's using custom HTTP handlers to handle inbound Web requests where each script request is pointing at an HTTP handler. In this case the handlers need to be individual files so I have a script map configured in IIS with a special extension and then mapped to my virtual directory. So the idea is that I can use a script call like this:

ScriptHandler.xrns

To make this work the xrns script extension must be mapped in IIS to the ASPNET_ISAPI.DLL (in classic ASP.NET mode at least) so that ASP.NET can handle requests of this extension.

The page is set up to run as an HTTP Handler:

<%@ WebHandler Language="C#"
        CodeBehind="InvestSecurityList.ashx.cs"
       
Class="SummaLPManager.InvestSecurityList"  %>

 

With the codebehind looking like this:

public class InvestSecurityList : ReportHttpHandler
{
    public override void Process()
    {
...
        Response.ContentType = "text/xml";
        Response.BinaryWrite(memXmlStream);
    }
}

The handler output always generates an XML response and there are various helpers that generate XML in a variety of ways.

To get the script file to run properly it's also necessary to add a BuildProvider (at least in a Web Application Project):

<configuration>
  <system.web> 
    <compilation defaultLanguage="c#" debug="true">
      <buildProviders>
        <add extension=".xrns" type="System.Web.Compilation.WebHandlerBuildProvider"/>        
      </buildProviders>
    </compilation>
  </system.web>
</configuration>

Without this the site refuses to run the actual extension even though it is mapped.

Custom Template in Visual Studio

This all works as expected, but when dealing with the custom extension content in Visual Studio  it doesn't do quite the right thing. Here's an example what an .ashx page and a .xrns page looks like in the project:

An added .ASHX handler automatically subjugates the source file underneath it in the project, but my custom script files that I've created don't. Internally VS.NET handles this inside of the project template which provides the association. For the .ashx handler it looks like this:

<ItemGroup>
  <Compile Include="PortfolioInfo.ashx.cs">
    <DependentUpon>PortfolioInfo.ashx</DependentUpon>
  </Compile>
  <Compile Include="PortfolioInfo.xrns.cs" />
 </ItemGroup>
<ItemGroup> 
  <Content Include="PortfolioInfo.ashx" />
  <None Include="PortfolioInfo.xrns" />
  <None Include="Web.config" />
</ItemGroup>

 Makes perfect sense... the ASHX file has a dependent upon mapping in the file but my xrns file of course does not.

Creating an association through the UI or a template?

But here's the $64,000 question: Is it possible to create this sort of association through the Visual Studio user interface or through use of a template? Basically what I want to do is allow my client to click on a template and create this xrns file and associated .cs file.

The template creation works fine and I get a nice preformatted source and script file which work just fine, but it creates the above listing in the project manager.

Anybody know if there's a way to create a template that can automatically can create the association?

Direct Handler Mapping?

Alternately, is there anyway to create just handler classes without any of the actual script pages? I was toying around with the idea of setting up a base handler that intercepts all requests for .xrns and then dynamically instantiate the appropriate class and fire the appropriate process method on it. I dynamically parse out the scriptname and based on that instantiate a class.

But that's kind of of scary to do because it gives potential access to just about any class which isn't exactly optimal. There are ways around this I suppose - like creating a marker interface, but this seems a little off the beaten track.

In essence I'm after an easy way to route inbound script calls directly to a given class, without having to individually map every request.

Posted in ASP.NET  IIS  IIS  

The Voices of Reason


 

DuncanS
March 30, 2007

# re: Nested Item Templates for custom script extensions in Visual Studio

Rick, I think you may be barking up the wrong tree with BuildProviders. This is what we use (and have been since .NET 1.0):

<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="Page*.ashx" validate="false" type="OurNamespace.OurHandlerFactory, OurAssembly"/>
</httpHandlers>

Which points at a IHttpHandlerFactory that acts as a Front Controller.

Rick Strahl
March 30, 2007

# re: Nested Item Templates for custom script extensions in Visual Studio

A handler factory isn't going to directly address my problem although in effect this is what it boils down to. The factory could be used to instantiate the appropriate class and then pass it back.

I'm not quite sure why the build provider is required to RUN the .xrns extension in VS.NET - I've never needed to actually do this with custom handlers but that might have been pre-.NET 2.0. Creating the entry took care of the runtime error.

What I ended up doing was create a small rewriting module that takes .xrns URLs and just routes them to the appropriate .ashx handlers. So our developers create their 'script' code in these handlers (either in the .ashx or codebehind) but the front end serves .xrns pages. We actually wanted the pages in order to be able to easily control acessibility/availability to scripts.

Works great, but I never managed to get the .xrns extension to properly show as an associated file pair in Visual Studio unless I manually edited the project file - ultimately that would have been the cleanest solution - full design time support for .xrns/.cs pair.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024