首页 文章

从 asp.net 类调用 MVC 视图会引发异常

提问于
浏览
0

我想获得 MVC 视图的 HTML。正在从 ASCX.CS 班级拨打电话。 (我正在尝试将 MVC View 注入 ASPX 页面)。我的 ASPX 页面是动态创建的(控件是从代码后面添加的)。

我找到了部分答案这里。唯一的问题是这个扩展方法是针对 MVC 控制器类的。

我在 ASCX.CS 的电话中做了什么:

fCatEve.Controllers.ASPXTestController test = new Controllers.ASPXTestController();
      string htmlView = test.RenderView("Index", null);

在这个动作中我唯一的问题是ControllerContext。我不知道如何设置这个类,所以它会找到我正在寻找的局部视图。

以下是我正在使用的方法(来自上面提到的页面):

public static class ControllerExtensions
{
    public static string RenderView(this Controller controller, string viewName, object model)
    {
        return RenderView(controller, viewName, new ViewDataDictionary(model));
    }

    public static string RenderView(this Controller controller, string viewName, ViewDataDictionary viewData)
    {
        RouteData routeData = new RouteData();
  routeData.Values.Add("controller", controller);
  var controllerContext = new ControllerContext { Controller = controller, RouteData = routeData };

  var viewResult = ViewEngines.Engines.FindView(controllerContext, viewName, null);

        StringWriter stringWriter;

        using (stringWriter = new StringWriter())
        {
            var viewContext = new ViewContext(
                controllerContext,
                viewResult.View,
                viewData,
                controllerContext.Controller.TempData,
                stringWriter);

            viewResult.View.Render(viewContext, stringWriter);
            viewResult.ViewEngine.ReleaseView(controllerContext, viewResult.View);
        }

        return stringWriter.ToString();
    }
}

例外是:

RouteData 必须包含名为“controller”的项目,其中包含 non-empty 字符串值。

在尝试第一个答案后,这里是异常的堆栈跟踪:

at System.Web.HttpContextBase.get_Items() at System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase context)System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext,String [8] locations,String [9] areaLocations,String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String [10]&searchingLocations)at System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext,String viewName ,String masterName,Boolean useCache)at System.Web.Mvc.ViewEngineCollection.Find(Func.<>c__DisplayClass6.b__4(IViewEngine e)at System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup,Boolean trackSearchedPaths)at System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext,String viewName,String masterName)at fCatEve.Helpers.ControllerExtensions.RenderView(Controller controller,String viewName,ViewDataDictionary viewData)in C:\ _ ProjectsG_Test - KOPIJA\fCatEve03 \解\ fCatEve \用 C fCatEve \助手\ ControllerExtensions.cs:line 43 fCatEve.Controls.KoledarReception.PutValuesToTabControlEVEBEVEN(Panel paControl,REFields REField):\ ProjectsG_Test - KOPIJA\fCatEve03 \解\ fCatEve\fCatEve\WF \控制\ KoledarReception.ascx.cs:line 2747 在 fCatEve.Controls.KoledarReception.PutValuesToTabControl()在 C:\ ProjectsG_Test - KOPIJA\fCatEve03 \解\ fCatEve\fCatEve\WF \控制\ KoledarReception.ascx.cs:line 2710 在 fCatEve.Controls.KoledarReception.Page_Load(Object 发件人,EventArgs e)如 C:\ ProjectsG_Test - KOPIJA\fCatEve03 \解\ fCatEve\fCatEve\WF \在 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object 发件人控制 KoledarReception.ascx.cs:line 817,EventArgs 的)在 System.Web.UI.Control.OnLoad(EventArgs e)在 System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Control.LoadRecursive() at System.Web.UI.Page.ProcessRequestMain(Boolean include_StagesBeforeAsyncPoin t,Boolean includeStagesAfterAsyncPoint)

2 回答

  • 1

    这是我用于我的单元测试之一的示例代码,该代码应该生成 PDF 文件,不确定它是否对您有任何好处。

    var controller = new MyAwesomePdfController();
    
    var httpRequest = new HttpRequest("", "http://mySomething", "");
    var stringWriter = new StringWriter();
    var httpResponse = new HttpResponse(stringWriter);
    var routeData = new RouteData();
    routeData.Values.Add("Controller", "MyAwesomePdf");  //must match your Controller name
    routeData.Values.Add("Action", "Receipt");  //must match your Action name
    
    var httpContextMock = new HttpContext(httpRequest, httpResponse)
    {
        //this is probably irrelevant to you, can set user principal here
        //User = new GenericPrincipal(
        //  new GenericIdentity(username),
        //  userRoles //new string[0]
        //)
    };
    
    controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock), routeData, controller);
    
    var receiptId = 1234;
    var pdfResult = await controller.Receipt(receiptId) as ViewAsPdf;  //should return a pdf file
    
  • 0

    我重写了调用(最重要的是:HttpContext.Current,后来在 MVC 中使用):

    fCatEve.Controllers.ASPXTestController test = new Controllers.ASPXTestController();
          string htmlView = test.RenderView("Index", null, HttpContext.Current);
    

    我还略微重写了两种方法:

    public static string RenderView(this Controller controller, string viewName, object model, HttpContext currentContext)
        {
          return RenderView(controller, viewName, new ViewDataDictionary(model), currentContext);
        }
    
        public static string RenderView(this Controller controller, string viewName, ViewDataDictionary viewData, HttpContext currentContext)
        {
          var routeData = new RouteData();
          routeData.Values.Add("Controller", "ASPXTest");  //must match your Controller name
          routeData.Values.Add("Action", "Test");  //must match your Action name
    
          HttpContextWrapper wrapper = new HttpContextWrapper(currentContext);
          controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
          var viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, null);
    
          StringWriter stringWriter;
          viewData = new ViewDataDictionary();
    
          using (stringWriter = new StringWriter())
          {
            var viewContext = new ViewContext(
                controller.ControllerContext,
                viewResult.View,
                viewData,
                controller.ControllerContext.Controller.TempData,
                stringWriter);
    
            viewResult.View.Render(viewContext, stringWriter);
            viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View);
          }
    
          return stringWriter.ToString();
        }
    

相关问题