在将基于MFC CHttpServer的web服务器转换为ASP.Net时,如何保留查询字符串语义?

在将基于MFC CHttpServer的web服务器转换为ASP.Net时,如何保留查询字符串语义?,asp.net,mfc,query-string,Asp.net,Mfc,Query String,在传统的基于MFC CHttpServer的web服务器中,我们有一个类似以下内容的命令解析映射: 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

在传统的基于MFC CHttpServer的web服务器中,我们有一个类似以下内容的命令解析映射:

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)
http://host/path/dllname.dll?MyPage?intParam4=32&strParam7=somestring
这定义了可在
http://host/path/dllname.dll?MyPage
最多可接受8个参数,分别命名为
intParam1
intParam2
intParam3
intParam4
strParam5
strParam6
strParam7
,以及
intParam8

调用应用程序可以使用以下命名方式调用带有参数的页面:

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)
http://host/path/dllname.dll?MyPage?intParam4=32&strParam7=somestring
但按照MFC命令解析映射的工作方式,只要按照映射定义的顺序提供,它们也可以使用未命名的参数调用它:

http://host/path/dllname.dll?MyPage?21&22&23&24&string5&string6&string7&28
我想用ASP.Net页面替换这段旧代码,但我们现有的调用应用程序不会更改,它们使用命名和未命名的参数传递样式调用页面

我可以轻松地管理必要的URL重写,以允许ASP.Net页面响应上述URL,替换路径/dllname.dll?带有.aspx页面或.ashx处理程序路径的MyPage部分

当试图以与旧MFC参数解析器等效的方式处理未命名参数时,问题就出现了。Request.QueryString将所有未命名的参数视为使用null命名,并且
Request.QueryString[null]
返回以逗号分隔的值列表。这几乎是可行的,但如果其中一个参数实际包含逗号,那么这种编码就会崩溃,因为多余的逗号不会转义,在逗号上拆分字符串将导致参数过多

在经典的ASP中,我相信
Request.QueryString(…)
返回了所有同名参数的集合。在ASP.Net中,我似乎找不到与之相当的东西

作为第二个问题,MFC命令解析映射有一些非常复杂的逻辑,用于处理命名参数和未命名参数的混合。尽管相关页面的调用者不会以这种方式混合使用,但为了完整性起见,我可能有兴趣复制逻辑。有人能确认MFC的行为本质上是以下行为吗

  • 使用&作为分隔符,从左到右处理URL中的所有参数。
    • 如果命名(具有等号),则将该值应用于具有相应名称的参数,而不管其位置如何。如果该参数已赋值,则返回错误
    • 如果未命名,则将该值应用于命令解析映射中第n个位置的参数,其中n是已处理的未命名参数数加1。如果已为该参数赋值,则返回错误
  • 将命令解析映射中的默认值应用于上面未指定的任何参数
  • 如果尚未为命令解析映射中的任何参数赋值,则返回错误

另一个有趣的注意事项是,
Request.QueryString.ToString()
几乎会重建URL上的原始参数,但它总是将具有相同名称的参数移动到一起,包括我在这里关注的未命名参数

不确定是否解决了问题,但您可以尝试使用Request.PathInfo。这将为您提供在页面之后输入的所有内容,然后您可以使用类似正则表达式的东西手动解析这些内容

例如,如果您有URL:

http://host/path/dllname.dll?MyPage?21&22&23&24&string5&string6&string7&28
Request.PathInfo属性将返回:

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

将其处理为一组可以使用的值也可能会有问题,因为您既有命名的参数,也有未命名的参数,但这应该可以通过使用正则表达式和/或拆分字符串来实现。

我发现
Request.QueryString
有一个
GetValues()
方法。这将返回一个字符串数组,并解决在其中一个值中嵌入逗号的问题。它甚至比拆分
Request.QueryString[null]
的结果更容易使用


我仍然需要做一些工作来使用它来实现类似MFC的URL参数映射,该映射处理命名和未命名参数。

我尝试了Request.PathInfo属性,它只获取“页面”之后的部分,直到但不包括“?”为止。如果我要自己解析这个,我想我需要使用Request.Url.Query属性。