2017-04-08 5 views
0

Ich möchte HTML der MVC-Ansicht erhalten. Der Anruf wird von der Klasse ASCX.CS ausgeführt. (Ich versuche, MVC View auf ASPX-Seite zu injizieren). Meine ASPX-Seite wird dynamisch erstellt (Steuerelemente werden aus dem Code dahinter hinzugefügt).Aufruf von MVC-Ansicht von asp.net-Klasse löst Ausnahme

Ich habe einen Teil der Antwort gefunden here. Das einzige Problem besteht darin, dass diese Erweiterungsmethode für die MVC-Controller-Klasse erstellt wurde.

Was ich in meinem Ruf zu tun von ascx.cs:

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

In dieser Aktion das einzige Problem, das ich habe ControllerContext ist. Ich weiß nicht, wie ich diese Klasse einstellen soll, also werde ich eine Teilansicht finden, nach der ich suche.

Hier sind Methoden verwende ich (ab Seite oben):

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

Die Ausnahme ist:

Die Routedata muss ein Element enthalten namens ‚Controller‘ mit einer nicht leeren Zeichenfolgewert

Nach dem ersten Antwort versuchen, hier Spur von Ausnahme-Stack:

bei System.Web.HttpContextBase.get_Items() bei System.Web.WebPages.DisplayModeProvider.GetDisplayMode (Httpcontextbase Kontext) bei System.Web.Mvc.VirtualPathProviderViewEngine.GetPath (Controller Controller, String [] Standorte, String [] areaLocations, String locationsPropertyName, String name, String controller, String cacheKeyPrefix, Boolean useCache, String [] 01.232.searchedLocations) bei System.Web.Mvc.VirtualPathProviderViewEngine.FindView (Controller Controller, String Viewname, String Mastername, Boolean useCache) bei System.Web.Mvc.ViewEngineCollection. <> c__DisplayClass6.b__4 (IViewEngine e) bei System.Web.Mvc.ViewEngineCollection.Find (Func`2 Lookup, Boolean trackSearchedPaths) bei System.Web.Mvc.ViewEngineCollection.FindView (Controller Controller, String Viewname, String Mastername) bei fCatEve.Helpers.ControllerExtensions.RenderView (Controller-Controller, String Viewname, Viewdatadictionary Viewdata) in C: \ ProjectsG_Test - kopija \ fCatEve03 \ Lösung \ fCatEve \ fCatEve \ Helfer \ ControllerExtensions.cs: Linie 43 an fCatEve.Controls.KoledarRepeption.PutValuesToTabControlEVEBEVEN (Panel paControl, REFields REField) in C: \ ProjectsG_Test - KOPIJA \ fCatEve03 \ Solution \ fCatEve \ fCatEve \ wf \ controls \ KoledarReception.ascx.cs: Linie 2747 bei fCatEve.Controls.KoledarReception.PutValuesToTabControl() in C: \ ProjectsG_Test - kopija \ fCatEve03 \ Lösung \ fCatEve \ fCatEve \ wf \ controls \ KoledarReception .ascx.cs: Linie 2710 bei fCatEve.Controls.KoledarReception.Page_Load (Object sender, EventArgse) in C: \ ProjectsG_Test - kopija \ fCatEve03 \ Lösung \ fCatEve \ fCatEve \ wf \ controls \ KoledarReception.ascx.cs : Zeile 817 um System.Web.Util.CalliEventHandlerDelegateProxy.Callback (Object sender, EventArgs e) bei System.Web.UI.Control.OnLoad (EventArgs e) um System.Web.UI.Control.LoadRecursive() um System.Web.UI.Control.LoadRecursive() um System.Web.UI.Control.LoadRecursive() bei System.Web.UI.Control.LoadRecursive() bei System.Web.UI.Control.LoadRecursive() bei System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

+0

können Sie versuchen, controllerContext mit constructor initialisieren: 'controller.ControllerContext = new ControllerContext (neuer HttpContextWrapper (httpContextMock), routeData, Controller);' –

+0

Dieser Code stammt von meinem Komponententest, was gut funktioniert. Aber wahrscheinlich nicht genau das, wonach du suchst. –

+0

Können Sie bitte Code für httpContextMock bereitstellen. Ich möchte das ausprobieren. – FrenkyB

Antwort

0

schrieb ich den Anruf (am wichtigsten: HttpContext.Current, die später in MVC verwendet wird):

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

ich etwas schrieb auch beide Methoden:

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

Hier ist ein Beispielcode ich für eine meiner Unit-Test verwenden, die eine PDF-Datei erzeugen soll, nicht sicher, ob es irgendwelche Vorteile für Sie hat.

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

Ich empfange 'Die Methode oder Operation ist nicht implementiert'. Obwohl die 'Aktion' mit dem angegebenen Namen auf dem Controller implementiert ist. – FrenkyB

+1

Veröffentlichen Sie Ihre Stacktrace –

+0

Ich habe in meine Frage eingefügt. – FrenkyB

Verwandte Themen