Wednesday, March 21, 2012

UrlRewrites and CascadingDropdown

I had forgotten that my framework re-writes paths using urlrewrite - it works that well ;)

Anyway, I have narrowed the problem down to this line in Page_Load to fix postbacks
Context.RewritePath(Path.GetFileName(Request.RawUrl));

This causes the service to stop working even if I specify the "real"path to the service using "~/path/subpath/service.asmx" syntax.
Neither does the "page" method work (not specifying a ServicePath)

My question: how to get the CascadingDropdown to work with RewritePath?Why is it necessary to rewrite the path of the web service?
I am not rewriting the URL of the webservice - how would you do that without some complex handler? =)

The problem seems to be that the CascadingDropdown is on a page that has the url rewritten, or more specifically, rewritten at page_load.
I'm not familiar with URL rewriting, but I think I see how that might break a page method (ServiceMethod blank, ServicePath set). However, I'd expect a web service call (ServiceMethod set, ServicePath set) to continue to work as long as the web service URL didn't change. Do I understand that that scenario isn't working for you either? Does it work if you disable the URL rewriting? Would it be possible to post a simple page demonstrating the problem?
In attempting to create a "simple" test I discovered that requests to webservices do not like path info appended to it at all - I was using that instead of querystrings as I only had a single "branch" parameter.

Anyway, after cleaning up the code to only append path info for .aspx pages, the service worked as expected.

Thanks
For anyone interested, here is the code I used to test this

Create urlReWriteTest.cs in App_Code:

using System;
using System.Web;

namespace QuoteEngine.Utils.Branding
{
public class urlReWriteTest
{
public static void Process()
{
Uri url = HttpContext.Current.Request.Url;
string branch;
/* a request is of the form:
* /<applicationpath>/<branch>/<rest of request>
* we map this to:
* /<applicationpath>/Engine/<rest of request>
*/if (url.Segments.Length > 3)
{
//get branch (first segment is "/", then application path, then "branch") branch = url.Segments[2].TrimEnd("/".ToCharArray());
string rest ="";
for (int i = 3; i < url.Segments.Length; i++)
{
rest += url.Segments[i];
}
if (HttpContext.Current.Request.Path.ToLower().EndsWith(".aspx")) {
HttpContext.Current.RewritePath(HttpContext.Current.Request.ApplicationPath +"/Engine/" + rest, branch, HttpContext.Current.Request.QueryString.ToString());
}else {
HttpContext.Current.RewritePath(HttpContext.Current.Request.ApplicationPath +"/Engine/" + rest,"", HttpContext.Current.Request.QueryString.ToString());
}
}

}
}
}

In Global.asax, add:

void Application_BeginRequest(object sender, EventArgs e) {
urlReWriteTest.Process();
}
A page needs:

protected void Page_Load(object sender, EventArgs e) {
Context.RewritePath(Path.GetFileName(Request.RawUrl));
}
So that the postbacks go to the right place.

You can then check the branch using either:

//take the path, split by /, what differs is our branchstring[] raw = Request.RawUrl.ToLower().Replace(Request.Url.Query,"").Split("/".ToCharArray());
string[] path = Request.Path.ToLower().Split("/".ToCharArray());
string branch =null;
for (int i = 0; i < path.Length; i++) {
if (raw[i] != path[i]) {
branch = raw[i];
break;
}
}
or
string branch = Request.PathInfo;
As only .aspx will have the PathInfo

Good luck and all thatBig Smile
Yes, I now learnt that all requests get rewritten, not just page request :P

No comments:

Post a Comment