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.