ASP.NET MVC中System.Web.UI.Page替代方案及调用转换报错解决
解决ASP.NET MVC控制器调用依赖System.Web.UI.Page方法的类型转换错误
你定义了如下依赖System.Web.UI.Page的ExecuteCommand方法,用于注册Web Forms异步任务:
public void ExecuteCommand(System.Web.UI.Page page, XmlDocument request, DeviceResponseHandler responseHandler, ExceptionHandler responseExceptionHandler) { page.RegisterAsyncTask(new System.Web.UI.PageAsyncTask( (sender, e, cb, extraData) => BeginCommand(request, cb, extraData), (ar) => { try { using (var resp = new DeviceResponse(this, ar)) responseHandler(resp); } catch (Exception ex) { responseExceptionHandler(ex); } }, null, null)); }
在ASP.NET MVC控制器中调用该方法时,传入控制器实例this:
session.ExecuteCommand(this, doc, (response) => { CmdGetNextGlogResponse cmd_resp = new CmdGetNextGlogResponse(); switch (cmd_resp.ParseResult(response.Xml)) { case CommandExeResult.OK: cmd_resp.Parse(response.Xml); break; default: string aed = "Failed!"; break; } }, (ex) => { string aed = ex.Message; });
触发类型转换错误:
Cannot convert controller to System.Web.Ui.Page
修正方案
方案1:重构方法,移除对Web Forms Page的依赖(推荐)
MVC控制器不属于Web Forms的Page体系,最合理的方式是重构ExecuteCommand,改用.NET原生异步模式,摆脱对Page.RegisterAsyncTask的依赖:
public async Task ExecuteCommand(XmlDocument request, DeviceResponseHandler responseHandler, ExceptionHandler responseExceptionHandler) { try { // 替换原BeginCommand的异步逻辑,用await完成异步操作 var asyncResult = BeginCommand(request, null, null); // 这里根据BeginCommand的实际逻辑,补充异步完成的等待逻辑,示例: // await Task.Factory.FromAsync(asyncResult, ar => EndCommand(ar)); using (var resp = new DeviceResponse(this, asyncResult)) { responseHandler(resp); } } catch (Exception ex) { responseExceptionHandler(ex); } }
控制器调用时,需将方法标记为async并使用await:
public async Task<ActionResult> YourActionMethod() { // 其他业务逻辑 await session.ExecuteCommand(doc, (response) => { CmdGetNextGlogResponse cmd_resp = new CmdGetNextGlogResponse(); switch (cmd_resp.ParseResult(response.Xml)) { case CommandExeResult.OK: cmd_resp.Parse(response.Xml); break; default: string aed = "Failed!"; break; } }, (ex) => { string aed = ex.Message; }); // 返回逻辑 return View(); }
方案2:临时兼容(不推荐,仅用于无法重构旧代码场景)
如果暂时无法重构原有方法,可以尝试从当前HttpContext获取Page实例(仅当请求上下文兼容Web Forms时有效):
var page = HttpContext.Current.Handler as System.Web.UI.Page; if (page != null) { session.ExecuteCommand(page, doc, (response) => { CmdGetNextGlogResponse cmd_resp = new CmdGetNextGlogResponse(); switch (cmd_resp.ParseResult(response.Xml)) { case CommandExeResult.OK: cmd_resp.Parse(response.Xml); break; default: string aed = "Failed!"; break; } }, (ex) => { string aed = ex.Message; }); }
注意:这种方式属于跨框架兼容,耦合度极高,容易引发上下文异常,仅作为临时过渡方案使用。
内容的提问来源于stack exchange,提问作者Prabhu
相关产品推荐
相关产品推荐

