介绍
本文提供了一种从ISAPI扩展的表单中检索post数据的方法。 还提供了两个有用的集合类参数。 由于非 MFC ISAPI扩展对速度和连接数的可以靠性更加可以靠,因这里不包括非MFC版本。功能
MFC和非MFC版本都使用向量。映射和基于基于,的类,而非MFC代码 inside。 在MFC版本中,字符串集合基于_bstr_t类型。 在非MFC版本中,字符串集合基于STL字符串类型。 所以,MFC版本使用基于的宏检索服务器变量和参数数据,而非MFC版本使用WriteClient
和 ServerSupportFunction
HTTP函数。使用复选框。编辑框。单选按钮。文本区域( 甚至是文件类型编辑框) 向浏览器写入一个复杂的表单。 它的思想是将所有的POST参数接收到相同的DLL扩展。 表单是使用 LoadLongResource
helper 函数从一个HTML字符串资源加载的。 这减少了构建页面所需的时间,因为字符串在第一次调用扩展时加载到内存中。 如何在你的Visual Studio 项目中使用HTML字符串资源它显示在我的ADO数据访问从 ISAPI 文章。
获取数据非常容易,因为使用URL从浏览器向服务器发送数据类型。 POST数据变量对用户透明,并且可以传输大量数据。 有关 GET/POST 数据的更多信息,请参见我的HTTP utility文章。
MFC版本
用于存储数据收集参数的C++ 类是Twin
和 TwinVector
。 ISAPI版本的默认方法将 IDR_HTML_FORM
资源写入客户端浏览器。 FormRequest
是在单击"提交查询"按钮后接收控件的方法。void CPostDataExtension::FormRequest(CHttpServerContext* pCtxt, void* pVoid, DWORD dwBytes) { //build the STL collection from server variables and POST data TwinVector vecServerCtx(pCtxt, (LPTSTR)pVoid); //write on browser stream the server context variables WriteServerData(pCtxt); //write on browser stream the STL collection of //server context variables and POST data WriteServerVar(pCtxt, vecServerCtx); }
一个小问题是从DLL入口点到 FormRequest
方法的控件。 在MFC下,使用宏执行操作非常简单:
DEFAULT_PARSE_COMMAND(FormRequest, CPostDataExtension) ON_PARSE_COMMAND(FormRequest, CPostDataExtension, ITS_RAW)要正确了解哪些方法将接收POST数据,MFC包装器必须从HTML表单接收一个隐藏参数:
<formaction="PostData.dll?"method=post><inputTYPE=hidden NAME="MfcISAPICommand"VALUE="FormRequest">
在 WriteServerVar
helper 函数中,服务器上下文变量集合是在HTTP流上编写的。 可以直接获取所需参数的值:bstrValue = vecServerCtx.Find(L"Filename").for (itVec = vecServerCtx.begin(); itVec!= vecServerCtx.end(); itVec++) *pCtxt <<<itVec->GetName() <<" =" <<<itVec-> GetValue() <<"br";

在相同的WriteServerVar
helper 函数中,POST数据收集以这种方式写入到HTTP流中。
bstrToken = L"DATA"; index = vecServerCtx.Find(bstrToken);if (index > -1) { map = vecServerCtx[index].GetValueAsMap(); if (!map.empty()) //we have valuesfor (itMap = map.begin(); itMap!= map.end(); itMap++) *pCtxt <<(*itMap).first <<" =" <<(*itMap).second <<"br"; }

可以直接获取所需参数的值:
*pCtxt <<"Filename =" <<map[L"Filename"] <<"br".</code>
TwinVector
类提供 VARIANT GetVariant()
方法和 TwinVector(VARIANT varSafe)
构造函数,以便在 COM+ 组件之间通过网络轻松传输集合。
非MFC版本
非MFC版本基于MSDN文章,关于ISAPI扩展中的发布数据。
C++ 扩展接收到的入口点在 DWORD WINAPI HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK pECB )
鏂规碜。
这里它启动了的Run
方法- 在我们的ISAPI扩展中运行一个运行对象。
用于保存数据集合中的参数的C++ 类是
MultipartParser和
MultipartEntry
。继承映射STL类型的cParser
变量接收完整的POST数据集合。 这是在 Initialize
方法中完成的。 GetParam
是一个 helper 方法,它返回所需参数的值。String CWriteFormExtension::GetParam(MultipartParser& cParser, String sName) { String sValue; //the output string MultipartEntry* pEntry = cParser[sName.c_str()]; if(pEntry!= NULL) //we have data { sValue = (LPCTSTR) pEntry->Data(); //get value from collection int nLen = sValue.size(); if(sValue[nLen - 1] == 'n' && sValue[nLen - 2] == 'r') sValue = sValue.substr(0, nLen - 2); } return sValue; }
这是 Run
方法的结果:
LoadLongResource
private 函数稍微有些修改。 输入/输出 str
字符串参数为STL字符串类型。 在 szPath
char变量中,我们必须放置DLL文件的名称,以加载正确的资源库。BOOL CWriteLayoutExtension::LoadLongResource(String &str, UINT nID) { HRSRC hRes; BOOL bResult = FALSE; CHAR szPath[MAX_PATH]; strcpy(szPath, "WriteForm.dll"); HINSTANCE hInst = LoadLibrary(szPath); //if you want standard html type hRes = FindResource(hInst, MAKEINTRESOURCE(nID), RT_HTML); if (hRes == NULL) { //trace error str = "Error: Resource could not be foundrn"; } else { DWORD dwSize = SizeofResource(hInst, hRes); if (dwSize == 0) { str.empty(); bResult = TRUE; } else { HGLOBAL hGlob = LoadResource(hInst, hRes); if (hGlob!= NULL) { LPVOID lpData = LockResource(hGlob); if (lpData!= NULL) { str = (LPCTSTR)lpData; bResult = TRUE; } FreeResource(hGlob); } } if (!bResult) str = "Error: Resource could not be loadrn"; } return bResult; }
历史记录
16 2002年07月 - 更新的MFC.zip 下载( 缺少一个类)