从asp.net类调用MVC视图会抛出异常

时间:2017-04-08 10:01:18

标签: c# asp.net asp.net-mvc

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

我找到了部分答案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必须包含名为' controller'的项目。非空的   字符串值。

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

  

在System.Web.HttpContextBase.get_Items()处   System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase   上下文)   System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext   controllerContext,String [] locations,String [] areaLocations,String   locationsPropertyName,String name,String controllerName,String   cacheKeyPrefix,Boolean useCache,String []& searchLocations)   System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext   controllerContext,String viewName,String masterName,Boolean   useCache)at   System.Web.Mvc.ViewEngineCollection<> c__DisplayClass6.b__4(IViewEngine   e)在System.Web.Mvc.ViewEngineCollection.Find(Func`2查找,   布尔trackSearchedPaths)at   System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext   controllerContext,String viewName,String masterName)at   fCatEve.Helpers.ControllerExtensions.RenderView(控制器控制器,   C:\ ProjectsG_Test中的String viewName,ViewDataDictionary viewData) -   KOPIJA \ fCatEve03 \解决方案\ fCatEve \ fCatEve \助手\ ControllerExtensions.cs:行   43点   fCatEve.Controls.KoledarReception.PutValuesToTabControlEVEBEVEN(图   paControl,REFields REField)在C:\ ProjectsG_Test中 -   KOPIJA \ fCatEve03 \解决方案\ fCatEve \ fCatEve \ WF \控制\ KoledarReception.ascx.cs:行   2747 at 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)在C:\ ProjectsG_Test中 -   KOPIJA \ fCatEve03 \解决方案\ fCatEve \ fCatEve \ WF \控制\ KoledarReception.ascx.cs:行   817在   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender,   EventArgs e)在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,Boolean includeStagesAfterAsyncPoint)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

decode("utf-16", errors='ignore')

我也略微改写了两种方法:

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