views:

193

answers:

2

In a legacy MFC CHttpServer based web server, we have a command parsing map something like this:

BEGIN_PARSE_MAP(MyHttpServer, CHttpServer)
    ON_PARSE_COMMAND(MyPage, MyHttpServer, ITS_I4 ITS_I4 ITS_I4 ITS_I4 ITS_PSTR ITS_PSTR ITS_PSTR ITS_I4)
    ON_PARSE_COMMAND_PARAMS("intParam1=11 intParam2=12 intParam3=13 intParam4=14 strParam5=s5 strParam6=s6 strParam7=s7 intParam8=18")
END_PARSE_MAP(MyHttpServer)

This defines a page accessible at http://host/path/dllname.dll?MyPage that accepts up to 8 parameters named intParam1, intParam2, intParam3, intParam4, strParam5, strParam6, strParam7, and intParam8.

The calling applications can invoke the page with the parameters in a named fashion like this:

http://host/path/dllname.dll?MyPage?intParam4=32&strParam7=somestring

But the way MFC command parsing maps work, they can also call it with unnamed parameters as long as they are provided in the order defined by the map:

http://host/path/dllname.dll?MyPage?21&22&23&24&string5&string6&string7&28

I would like to replace this old code with an ASP.Net page, but we have existing calling applications that will not be changed that invoke the page using both styles of parameter passing, named and unnamed.

I can easily manage the necessary URL rewriting to allow an ASP.Net page to respond to the URL as given above, replacing the path/dllname.dll?MyPage portion with the path to an .aspx page or .ashx handler.

The problem comes in when trying to handle the unnamed parameters in an equivalent fashion to the old MFC parameter parser. Request.QueryString treats all the unnamed parameters as being named with null and Request.QueryString[null] returns a comma-separated list of the values. This is pretty close to workable, but should one of the parameters actually contain a comma, this encoding falls apart because the extra comma is not escaped and splitting the string on the commas will end up with too many parameters.

In classic ASP, I believe Request.QueryString(...) returned a collection of all the parameters that were identically named. There seems to be no equivalent to that in ASP.Net that I can find.

As a secondary issue, the MFC command parsing map had some pretty convoluted logic for dealing with a mixture of named and unnamed parameters. Although the callers of the page in question will not be mixing their usage in this way, I am interested in perhaps duplicating the logic for completeness sake. Can anyone confirm that MFC's behavior was essentially the following?

  • Process all parameters in the URL from left to right, using & as separator.
    • If named (has an equal sign), apply the value to the parameter with the corresponding name, regardless of its position. If that parameter already assigned a value, error.
    • If unnamed, apply the value to the parameter at the nth position in the command parsing map, where n is the number of already processed unnamed parameters plus 1. If that parameter was already assigned a value, error.
  • Apply default values from command parsing map to any parameters not assigned above
  • If any parameters from command parsing map have not been assigned a value, error.

One more interesting note, it appears that Request.QueryString.ToString() will nearly reconstitute the original parameters on the URL, but it always moves the parameters with identical names to be together, including the unnamed parameters I am concerned with here.

A: 

Not sure if solves your problem, but you could try using Request.PathInfo. This will give you everything entered after the page, which you could then parse manually using something like a regex.

For example, if you had the URL:

http://host/path/dllname.dll?MyPage?21&22&23&24&string5&string6&string7&28

The Request.PathInfo property would return:

?MyPage?21&22&23&24&string5&string6&string7&28

Processing this into a set of values that you can work with could also be problematic as you've got both named and un-named parameters, but this should be achievable using regular expressions and/or splitting the string.

Mun
I tried the Request.PathInfo property and it only gets the portion after the "page" and up to but not including the "?". If I am going to parse this myself, I think I need to use the Request.Url.Query property.
GBegen
A: 

I found that Request.QueryString has a GetValues() method. This returns an array of strings and solves the problem of a comma being embedded within one of the values. It'll be even easier to use than having to split the results of Request.QueryString[null].

I still have a bit of work to use this to implement an MFC-like mapping of URL parameters that handles both named and unnamed parameters.

GBegen