2017-04-08 47 views
0

我想获得MVC视图的HTML。正在从ASCX.CS类呼叫。 (我试图注入MVC​​视图到ASPX页面)。 我的ASPX页面是动态创建的(控件是从后面的代码中添加的)。从asp.net类调用MVC视图抛出异常

我找到答案的一部分here。唯一的问题是这个扩展方法是为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必须包含一个名为“控制器”项目与非空 字符串值。

首先尝试回答后,这里是堆栈异常的痕迹:

在System.Web.HttpContextBase.get_Items()在 System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase 上下文) at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext,String [] locations,String [] areaLocations,String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String [] &个searchedLocations)在 System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext,字符串的viewName,字符串masterName,布尔 useCache将)在 System.Web.Mvc.ViewEngineCollection。 <> c__DisplayClass6.b__4(IViewEngine e)上System.Web.Mvc.ViewEngineCollection.Find(Func`2查找, 布尔trackSearchedPaths)在 System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext,字符串的viewName,字符串masterName)在 fCatEve.Helpers.ControllerExtensions.RenderView(控制器的控制器, 字符串的viewName,可视数据的ViewDataDictionary)在C:\ ProjectsG_Test - KOPIJA \ fCatEve03 \解\ fCatEve \ fCatEve \助手\ ControllerExtensions.cs:线 43在 fCatEve.Controls.KoledarReception.PutValuesToTabControlEVEBEVEN(Panel paControl,REFields REField)in C:\ ProjectsG_Test - KOPIJA \ fCatEve03 \ Solution \ fCatEve \ fCatEve \ WF \控制\ KoledarReception.ascx.cs:线 2747在fCatEve.Controls.KoledarReception.PutValuesToTabControl() 在C:\ ProjectsG_Test - KOPIJA \ fCatEve03 \解\ fCatEve \ fCatEve \ WF \控制\ KoledarReception .ascx.cs:行 2710 at fCatEve.Controls.KoledarReception.Page_Load(Object sender, EventArgs e)in C:\ ProjectsG_Test - KOPIJA \ fCatEve03 \ Solution \ fCatEve \ fCatEve \ wf \ Controls \ KoledarReception.ascx.cs :行 817在 System.Web.Util.CalliEventHandlerDelegateProxy。回调(Object sender, EventArgs e)at System.Web.UI.Control.OnLoad(EventArgs e)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.Control.LoadRecursive()at System.Web.UI.Page.ProcessRequestMain()布尔 includeStagesBeforeAsyncPoint,布尔includeStagesAfterAsyncPoint)

+0

你可以尝试使用构造函数初始化controllerContext:'controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock),routeData,controller);' –

+0

该代码是从我的单元测试,它工作正常。但可能不是你正在寻找的。 –

+0

请问您可以提供httpContextMock的代码吗?我想尝试一下。 – FrenkyB

回答

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(); 
    } 
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

我收到'方法或操作未执行'。虽然名字给出的'Action'在控制器上实现。 – FrenkyB

+1

发布你的堆栈跟踪 –

+0

我粘贴到我的问题。 – FrenkyB