2017-04-08 50 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