urlMappings interaction with web.config hierarchy

L

Luke Dalessandro

I have an application with the following layout

/root/
/root/Default.aspx
/root/web.config
/root/child/
/root/child/web.config


web.config has a custom configuration section "testSection" with the
basic layout of:

<testSection>
<tests>
<add id="" value="" />
</tests>
</testSection>

The root web.config defines:

<testSection>
<tests>
<add id="test1" value="root1" />
<add id="test2" value="root2" />
</tests>
</testSection>

the child web.config defines:

<testSection>
<tests>
<remove id="test2" />
<add id="test2" value="child2" />
<add id="test3" value="child3" />
</tests>
</testSection>

finally, the root web.config defines the url mapping:

<urlMappings enabled="true">
<add url="~/root/child/Default.aspx"
mappedUrl="~/root/Default.aspx"/>
</urlMappings>

Essentially, my goal is, for the url "~/root/child/Default.aspx", I want
to run the file "~/root/Default.aspx" BUT, I want it run as if were
located at "~/root/child/Default.aspx", inheriting the child defined
web.config.

Can someone point me towards the solution? As it is now, the page gets
run as if it were located where it is actually located, and no
web.config accumulation is done. Presumably I either need a way to
manually load configuration files before the Rewrite happens, or I need
a way to execute a .aspx class as if it were located at a different
location. I imagine that the first way is the better way to go, as
everything else (urls etc) should be processed as if the file were
executing at it's actual location.

I just need a starting point. I have written custom url mapping
modules, but nothing I know how to do will allow me to solve my problem.

Thanks in advance,
Luke
 
L

Luke Dalessandro

Luke said:
I have an application with the following layout

/root/
/root/Default.aspx
/root/web.config
/root/child/
/root/child/web.config


web.config has a custom configuration section "testSection" with the
basic layout of:

<testSection>
<tests>
<add id="" value="" />
</tests>
</testSection>

The root web.config defines:

<testSection>
<tests>
<add id="test1" value="root1" />
<add id="test2" value="root2" />
</tests>
</testSection>

the child web.config defines:

<testSection>
<tests>
<remove id="test2" />
<add id="test2" value="child2" />
<add id="test3" value="child3" />
</tests>
</testSection>

finally, the root web.config defines the url mapping:

<urlMappings enabled="true">
<add url="~/root/child/Default.aspx"
mappedUrl="~/root/Default.aspx"/>
</urlMappings>

Essentially, my goal is, for the url "~/root/child/Default.aspx", I want
to run the file "~/root/Default.aspx" BUT, I want it run as if were
located at "~/root/child/Default.aspx", inheriting the child defined
web.config.

Can someone point me towards the solution? As it is now, the page gets
run as if it were located where it is actually located, and no
web.config accumulation is done. Presumably I either need a way to
manually load configuration files before the Rewrite happens, or I need
a way to execute a .aspx class as if it were located at a different
location. I imagine that the first way is the better way to go, as
everything else (urls etc) should be processed as if the file were
executing at it's actual location.

I just need a starting point. I have written custom url mapping
modules, but nothing I know how to do will allow me to solve my problem.

Thanks in advance,
Luke

Ok,

An update for anyone who cares. I've got this working by using a custom
IHttpHandler. Essentially, I check all incoming requests for existence.
If they exist, I process them normally.

If they don't exist, and a "searchParent" flag is set in the
configuration file for the current execution directory, I strip the last
directory from the url, and check for existence. This runs recursively
until I find the file, I hit the application root directory, or I hit a
directory where parent searching isn't enabled.

Just as an aside, to load a web configuration file from a directory
that's not the currently execution directory, use the GetSection(string,
string) version of GetSection, passing the path to the file as the
second parameter. This is necessary because I'm never actually Rewriting
the context url, I'm just doing a directory search.

The magic that happens is that, in the IHttpHandler, the method that I
am using to execute the page is PageParser.GetCompiledPageInstance. This
takes three parameters, the first two specify the page to run, and the
third is the context to run in.

By loading the page that I've found, with the context that still lists
the current execution path, the page loads as if it were at the
requested location. Essentially, this is sort of a url rewrite without
changing the context.

Caveats:

I'm not sure if this causes POST problems, or cache strangeness.
I'm still looking into it.

I've found that if I have an actual url rewriting module that
runs before I run this execution file search, I need to pass
"false" as the second parameter to context.RewritePath() or Urls
are not resolved correctly by the page. I'm not sure if this is
a RewritePath problem or specific to instantiating a page that
doesn't actually reside where the context thinks it does.

VirtualPathProvider seems to offer customization potential, but
I haven't been able to figure it out yet.

I'll post any more issues I run into for anyone paying attention. Hope
this helps if you're trying to do something like this.

Luke
 
L

Luke Dalessandro

Luke said:
Ok,

An update for anyone who cares. I've got this working by using a custom
IHttpHandler. Essentially, I check all incoming requests for existence.
If they exist, I process them normally.

If they don't exist, and a "searchParent" flag is set in the
configuration file for the current execution directory, I strip the last
directory from the url, and check for existence. This runs recursively
until I find the file, I hit the application root directory, or I hit a
directory where parent searching isn't enabled.

Just as an aside, to load a web configuration file from a directory
that's not the currently execution directory, use the GetSection(string,
string) version of GetSection, passing the path to the file as the
second parameter. This is necessary because I'm never actually Rewriting
the context url, I'm just doing a directory search.

The magic that happens is that, in the IHttpHandler, the method that I
am using to execute the page is PageParser.GetCompiledPageInstance. This
takes three parameters, the first two specify the page to run, and the
third is the context to run in.

By loading the page that I've found, with the context that still lists
the current execution path, the page loads as if it were at the
requested location. Essentially, this is sort of a url rewrite without
changing the context.

Caveats:

I'm not sure if this causes POST problems, or cache strangeness.
I'm still looking into it.

I've found that if I have an actual url rewriting module that
runs before I run this execution file search, I need to pass
"false" as the second parameter to context.RewritePath() or Urls
are not resolved correctly by the page. I'm not sure if this is
a RewritePath problem or specific to instantiating a page that
doesn't actually reside where the context thinks it does.

VirtualPathProvider seems to offer customization potential, but
I haven't been able to figure it out yet.

I'll post any more issues I run into for anyone paying attention. Hope
this helps if you're trying to do something like this.

Luke

Update:

This isn't working entirely perfectly. When a url like
"~/root/child/Default.aspx" is processed by "~/root/Default.aspx"
without RewritingPath, almost everything is exactly right. Urls are
based on "~/root/child/" correctly, and calls to
WebConfigurationManager.GetSection("custom") all reflect the web.config
file at "~/root/child/web.config" like I want.

The problem is that NON-custom web.config configuration data is coming
from "~/root/web.config". For instance, if I have a <pages
masterPathFile="root.master" theme="root" /> declared at the "~/root/"
level, and a <pages masterPathFile="child.master" theme="child" />
declared at the child level, the page is displaying the root
theme/master rather than the child theme/master, as I want it to (this
is for an execution directory of "~/root/child/Default.aspx").

I don't understand why, if my custom configuration sections are
available via GetSection("custom") without a path parameter, the page
wouldn't be seeing the built-in configuration sections from the same
web.config.

If anyone's following this I could use some help. I can work around this
for now by defining a custom configuration section where I can specify
my own themes/masters, and then putting custom theme/master loading code
in a default page class base, but I'm not sure what other functionality
I need in the future (things like access control etc).

Thanks,
Luke
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top