[英]Calling MVC view from asp.net class throws exception
我想獲取MVC視圖的HTML。 正在從ASCX.CS類進行調用。 (我正在嘗試將MVC視圖注入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”的項目,該項目的字符串值為非空。
在嘗試了第一個答案之后,這是異常的堆棧跟蹤:
在System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase context)在System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext,String [] location,String [] areaLocations,字符串locationPropertyName ,位於System.Web.Mvc.VirtualPathProviderViewEngine.FindView的字符串,字符串名稱,字符串controllerName,字符串cacheKeyPrefix,布爾useCache,字符串[]和searchedLocations)(位於System.Web.Mvc.ViewEngineCollection的ControllerContext controllerContext,字符串viewName,字符串masterName,布爾useCache)。 。<> c__DisplayClass6.b__4(IViewEngine e)在System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext,String viewName,String masterName)在System.Web.Mvc.ViewEngineCollection.FindView(Controller2 controller,Boolean trackSearchedPaths) fCatEve.Helpers.ControllerExtensions.RenderView(控制器控制器,字符串viewName,ViewDataDictionary viewData)在C:\\ ProjectsG_Test-KOPIJA \\ fCatEve03 \\ Solution \\ fCatEve \\ fCatEve \\ Helpers \\ ControllerExtensions.cs:fCatEve.Controls.KoledarReception.PutValuesToTabControlEVEBEVEN(Panel paControl,REFields REField)的第43行位於C:\\ ProjectsG_Test-KOPIJA \\ fCatEve03 \\ Solution \\ fCatEve \\ E \\ CatEve \\ Ec ascx.cs:C:\\ ProjectsG_Test中的fCatEve.Controls.KoledarReception.PutValuesToTabControl()的第2747行-KOPIJA \\ fCatEve03 \\ Solution \\ fCatEve \\ fCatEve \\ wf \\ Controls \\ KoledarReception.ascx.cs:eC的第2710行。 .Page_Load(Object sender,EventArgs e)in C:\\ ProjectsG_Test-KOPIJA \\ fCatEve03 \\ Solution \\ fCatEve \\ fCatEve \\ wf \\ Controls \\ KoledarReception.ascx.cs:System.Web.Util.CalliEventHandlerDelegateProxy.Callback的817行,System.Web.UI.Control.OnLoad上的EventArgs e)(System.Web.UI.Control.LoadRecursive()上System.Web.UI.Control.LoadRecursive()的System.Web.UI.Control.LoadRecursive()的EventArgs e) System.Web.UI.Control.LoadRecursive()的System.Web.UI.Control.LoadRecursive()的System.Web.UI.Page.ProcessRequ的.LoadRecursive() estMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)
這是我用於其中一個單元測試的示例代碼,該代碼應該生成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
我重寫了該調用(最重要的是: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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.