我正在尝试在应用程序中使用的 .NET 类库中使用来自 ASP 应用程序的请求元素。我遇到了一个令人头疼的问题,我无法理解:
//Context is an ASPTypeLibrary.ScriptingContext
dynamic req = System.EnterpriseServices.ContextUtil.GetNamedProperty("Request");
Context.Response.Write(req.Form("mykey")); //this writes the value I expected
Context.Response.Write(String.Format("{0}", req.Form("mykey"))); //this writes 'System.__ComObject'
我的想法是错的吗?我正在使用从 this question 收集的信息.
最佳答案
您应该注意 Request.Form("someKey")
不是 字符串
。然而,您的困惑的根源不是来自 Request.Form("someKey")
,而是来自另一边的 Response.Write(...)
。
正在发生一些自动转换恶作剧。
Request.Write(...)
不接受字符串
。它需要一个Variant
。该方法将尽最大努力输出您传递给它的任何内容。
如果Variant
包含BSTR
(COM 字符串),它将按原样输出。它还会尝试调用 VarChangeTypeEx(...)
(类似;参见下面的注释)来尝试查看是否可以让 COM 将其转换为 BSTR
(这就是当你传递一个数字时会发生的情况)。如果 Variant
包含一个带有默认方法的对象 ([propvalue]),并且没有更好的方法来输出它,它将调用默认方法并以结果重新开始。我认为它还有其他一些技巧,但没有完全清楚地记录下来。
从高层来看,现在发生的事情应该很清楚了。在第一行,req.Form("myKey")
返回一个 COM 对象,然后将其传递给 Response.Write(...)
,然后将其转换将该对象转换为 BSTR
字符串并输出它。另一方面,当您尝试将 req.Form("myKey")
传递给 C# 方法时,不会发生转换,而是得到一个通用 COM 对象,其后果是可预测的。
那么Request.Form("someKey")
的返回值是什么呢?这是一个 IRequestDictionary
对象。为什么要有字典?因为您可以提交一个包含多个同名表单元素的 http 请求。例如,当输入元素是旨在重叠选项的复选框时,可能会出现这种情况。
当表单有多个条目时会发生什么?转换过程返回一个连接字符串,类似于 C# 中的 String.Join(", ", someArray)
。
我不清楚 Response.Write
是否深入了解 IRequestDictionary
(不太可能),或者它是否了解 COM 枚举器模式(更有可能)并枚举他们组成字符串。
对我来说更有趣的是谁负责转换过程,因为 VBScript 的 CStr()
将执行相同的转换。我一直认为 CStr()
是 VarChangeTypeEx(...)
的薄包装,但我很确定 VarChangeTypeEx(...)
不会像那样连接枚举器。显然 CStr()
比我想象的要花哨得多。我相信 Response.Write 只是在内部调用任何完全实现 CStr()
的 API,并依赖它进行转换。
要进一步探索经典 ASP 对象和界面,请尝试 http://msdn.microsoft.com/en-us/library/ms524856(v=vs.90).aspx 而不是通常的基于 VBScript 的描述。
关于c# - 在 C# 中使用 ASP ScriptingContext 请求集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23643511/