2016-03-29 5 views
0

Ich habe MVC-Controller mit Aktion, die Teilansicht zurückgibt. Aktion enthält viel Logik und sendet Daten im ViewBag-Objekt.Teilansicht in String mit Calling-Controller-Aktion zu transformieren

Ich muss Ergebnis dieser Aktion in Zeichenfolge rendern und dann als E-Mail senden. Alle Lösungen, die ich gefunden habe, rendern Ansicht ohne Aktion aufrufen.

Ist es möglich, irgendwo in meinem Code den Controller zu initialisieren, die Aktionsmethode aufzurufen und ActionResult (das heißt Teilansicht) in eine Zeichenfolge umzuwandeln?

Thx

+0

Wenn Sie diese E-Mails verwenden Sie können wie in etwas aussehen wollen [MvcMailer] (https://www.nuget.org/packages/MvcMailer), die ziemlich genau das tut, was Sie suchen. Ich hatte in der Vergangenheit Erfolg damit und es ist einfach zu implementieren. – zgood

Antwort

0

Ich habe es getan. Mit viel Schmerz.

Zuerst müssen wir Controller ohne Kontext initiieren. Dazu verwende ich Rick Strahl-Methode namens CreateController

public static T CreateController<T>(RouteData routeData = null) 
     where T : Controller, new() 
    { 
     // create a disconnected controller instance 
     T controller = new T(); 

     // get context wrapper from HttpContext if available 
     HttpContextBase wrapper = null; 
     if (HttpContext.Current != null) 
      wrapper = new HttpContextWrapper(System.Web.HttpContext.Current); 
     else 
      throw new InvalidOperationException(
       "Can't create Controller Context if no active HttpContext instance is available."); 

     if (routeData == null) 
      routeData = new RouteData(); 

     // add the controller routing if not existing 
     if (!routeData.Values.ContainsKey("controller") && !routeData.Values.ContainsKey("Controller")) 
      routeData.Values.Add("controller", controller.GetType().Name 
                 .ToLower() 
                 .Replace("controller", "")); 

     controller.ControllerContext = new ControllerContext(wrapper, routeData, controller); 
     return controller; 
    } 

Quelle: http://weblog.west-wind.com/posts/2013/Jul/15/Rendering-ASPNET-MVC-Razor-Views-outside-of-MVC-revisited

Aber wenn Sie diese Methode aufrufen, wenn Httpcontext es wird Ausnahme auslösen. Um zu verhindern, dass ich falschen Kontext mit diesem Code initiiere: https://stackoverflow.com/a/19709225/1850880.

Dann initiiere ich Controller und Call-Aktion. Ergebnis dieser Aktion enthält viewData mit allen Daten, die von Aktion übergeben wurden. Wir können es mit Reflektion (wie ein Ninja) bekommen. Und dann können wir Ansicht auf String mit übergebenem Modell rendern.

 var controller = CreateController<ControllerName>(); 
     var result = controller.ActionName(param1, param2); 
     object viewData = result.GetType().GetProperty("ViewData").GetValue(result); 
     object values = viewData.GetType().GetProperty("Values").GetValue(viewData); 
     var str = ec.RenderRazorViewToString("ViewName", values); 
     return str; 

Diese Methode im Hinblick auf String-Render:

public static string RenderRazorViewToString(this Controller controller, string viewName, object model) 
    { 
     controller.ViewData.Model = model; 
     controller.ViewBag.Model = model; 
     using (var sw = new StringWriter()) 
     { 
      var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 
      var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); 
      viewResult.View.Render(viewContext, sw); 
      viewResult.ViewEngine.ReleaseView(controller.ControllerContext, viewResult.View); 
      return sw.GetStringBuilder().ToString(); 
     } 
    } 

Sieht aus wie es nicht der beste Weg ist, aber es funktioniert. Also, wenn Sie irgendwelche Ideen haben, schreiben Sie unbedingt.