Wie render eine ASP.NET MVC view als string?
Möchte ich die Ausgabe mit zwei verschiedenen Ansichten (als ein string, der gesendet wird, als eine E-Mail), und die andere die Seite für den Benutzer angezeigt.
Ist dies möglich ASP.NET MVC beta?
Habe ich versucht mehrere Beispiele:
1. RenderPartial String in ASP.NET MVC Beta
Wenn ich dieses Beispiel verwenden, erhalte ich die "Nicht umleiten nach HTTP
Kopfzeilen gesendet wurden.".
2. MVC-Framework: die Erfassung der Ausgabe eines Sicht
Wenn ich diese, ich scheine unfähig zu sein, zu tun, eine redirectToAction, wie es
versucht das Rendern einer Ansicht, die nicht existieren kann. Wenn ich Rückkehr die Ansicht, es
ist komplett Durcheinander und sieht nicht Recht.
Hat jemand irgendwelche Ideen/Lösungen für diese Probleme, die ich habe, oder haben Sie irgendwelche Vorschläge für besseres?
Vielen Dank!
Unten ist ein Beispiel. Was ich bin versucht zu tun ist erstellen Sie die GetViewForEmail Methode:
public ActionResult OrderResult(string ref)
{
//Get the order
Order order = OrderService.GetOrder(ref);
//The email helper would do the meat and veg by getting the view as a string
//Pass the control name (OrderResultEmail) and the model (order)
string emailView = GetViewForEmail("OrderResultEmail", order);
//Email the order out
EmailHelper(order, emailView);
return View("OrderResult", order);
}
Akzeptiert die Antwort von Tim Scott (geändert formatiert und ein wenig von mir):
public virtual string RenderViewToString(
ControllerContext controllerContext,
string viewPath,
string masterPath,
ViewDataDictionary viewData,
TempDataDictionary tempData)
{
Stream filter = null;
ViewPage viewPage = new ViewPage();
//Right, create our view
viewPage.ViewContext = new ViewContext(controllerContext, new WebFormView(viewPath, masterPath), viewData, tempData);
//Get the response context, flush it and get the response filter.
var response = viewPage.ViewContext.HttpContext.Response;
response.Flush();
var oldFilter = response.Filter;
try
{
//Put a new filter into the response
filter = new MemoryStream();
response.Filter = filter;
//Now render the view into the memorystream and flush the response
viewPage.ViewContext.View.Render(viewPage.ViewContext, viewPage.ViewContext.HttpContext.Response.Output);
response.Flush();
//Now read the rendered view.
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally
{
//Clean up.
if (filter != null)
{
filter.Dispose();
}
//Now replace the response filter
response.Filter = oldFilter;
}
}
Beispiel für die Verwendung
Vorausgesetzt, ein Aufruf aus dem controller zu Holen Sie sich die Bestätigungs-E-Mail, vorbei an der Website.Master-Standort.
string myString = RenderViewToString(this.ControllerContext, "~/Views/Order/OrderResultEmail.aspx", "~/Views/Shared/Site.Master", this.ViewData, this.TempData);
- Wie können Sie diese mit einer Ansicht, die stark typisiert ist? Dh. wie kann ich feed ein Modell auf die Seite?
- Dies nicht verwenden können, und erstellen Sie JsonResult danach, da der content-Typ nicht festgelegt werden können, nachdem die Header gesendet wurden (weil Flush sendet Ihnen).
- Denn es gibt keine einzige richtige Antwort, nehme ich an. 🙂 Ich erstellte eine Frage, die war spezifisch für mich, aber ich wusste, dass es wäre eine weithin fragte einer, als gut.
- Die vorgeschlagene Lösung funktioniert nicht in MVC 3.
- Die vorgeschlagene Lösung ist über zwei Jahre alt. Ich würde nicht erwarten, dass es funktioniert für MVC-3 an! Außerdem gibt es bessere Möglichkeiten, dies jetzt zu tun.
- Danke. Behoben!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist, was ich kam mit, und es ist für mich arbeiten. Hinzugefügt habe ich folgende Methode(N) für mein controller-Basisklasse. (Kann man immer machen, diese statischen Methoden irgendwo sonst akzeptieren, dass ein controller als parameter nehme ich an)
MVC2 .ascx-Stil
Razor .cshtml-Stil
Edit: Hinzugefügt Razor-code.
RenderPartialToString
Methode. Deine Lösung funktioniert perfekt.writer
parameter der ViewContext Constructer, um diese zu kompilieren, dann bekomme ich aber eineMissingMethodException
, das finde ich sehr merkwürdig.ControllerContext
ist Mitglied der Controller, wenn ich mich nicht Irre, also sollte es nicht statisch sein.ViewEngines
. Keine Hilfe?ViewData.ModelState.Clear();
am Anfang der Methode.Diese Antwort ist nicht auf meinem Weg . Dieser ist ursprünglich aus https://stackoverflow.com/a/2759898/2318354 aber hier habe ich den Weg zu zeigen, verwenden Sie es mit "Static" Schlüsselwort, um es gemeinsam für alle Regler .
Für die, die Sie haben, um
static
Klasse in der Klasse Datei . (Angenommen, deine Klasse File Name Utils.cs )Diesem Beispiel ist Für die Razor.
Utils.cs
Rufen Sie nun diese Klasse von deinem controller durch hinzufügen von NameSpace in einer Controller-Datei als folgende Weise, indem Sie "this" als parameter auf den Controller.
Als Anregung gegeben durch @Sergey diese Erweiterung Methode kann auch vom regler wie unten angegeben
Ich hoffe, dass dies nützlich sein wird, um Sie den code sauber und ordentlich.
ViewEngines
. Wissen Sie, wie Sie diesen Fehler beheben?ViewContext
keine controller-parameter :/ irgendeine Idee ?Diese funktioniert bei mir:
Ich eine neue Lösung gefunden, das macht ein Blick auf string die zimmerreserviereung, ohne das Durcheinander mit den Response-stream des aktuellen HttpContext (die kann man nicht ändern die Antwort ist ContentType oder andere Header).
Im Grunde alles, was Sie tun ist, erstellen Sie eine gefälschte HttpContext für die Ansicht zu Rendern selbst:
Dieser Werke auf ASP.NET MVC 1.0, zusammen mit ContentResult, JsonResult, etc. (wechselnde Header in der ursprünglichen HttpResponse nicht werfen nicht das "Server nicht Inhaltstyp nach dem HTTP-Header gesendet wurden" Ausnahme).
Update: in ASP.NET MVC 2.0 RC, den code etwas verändert, weil wir zu Durchlaufen haben, in der
StringWriter
geschrieben, der Blick in denViewContext
:StringWriter
Sie verwenden, um zu schreiben, um dieStringBuilder
, nicht eine neue Instanz oder die Ausgabe von der view verloren.Dieser Artikel beschreibt, wie das Rendern einer Ansicht auf eine Zeichenfolge, die in verschiedenen Szenarien:
Die Lösung/code ist eine Klasse namens " ViewRenderer. Es ist Teil von Rick Stahl WestwindToolkit auf GitHub.
Nutzung (3. - WebAPI Beispiel):
Wenn Sie verzichten wollen, MVC vollständig, wodurch alle HttpContext Durcheinander...
Dies nutzt der awesome open-source-Razor-Engine hier:
https://github.com/Antaris/RazorEngine
CompilerErrors
- Eigenschaft der Ausnahme.Sie erhalten die Ansicht in eine Zeichenkette mit dieser Art
Wir nennen diese Methode in zwei-Wege -
ODER
Ich bin mit MVC 1.0 RTM und keine der oben genannten Lösungen bei mir funktioniert. Aber dieser Tat:
Sah ich, wie eine Umsetzung für MVC 3 und Razor auf einer anderen website, es funktionierte für mich:
Mehr auf Razor render - MVC3-Ansicht Rendern String
Rendern einer Ansicht auf eine Zeichenfolge in der Service-Schicht ohne pass ControllerContext herum, es ist eine gute Rick Strahl Artikel hier http://www.codemag.com/Article/1312081 das schafft eine generische controller. Code summary unter:
Dann zum Rendern der Ansicht in der Service-Klasse:
Quick-Tipp
Für eine stark typisierte Modell fügen Sie ihn einfach in das ViewData.Model-Eigenschaft, bevor Sie zum RenderViewToString. e.g
Wiederholen von einem eher unbekannten Frage, werfen Sie einen Blick auf MvcIntegrationTestFramework.
Macht es erspart Ihnen das schreiben Ihrer eigenen Helfer, um Strom führen und ist nachweislich gut genug funktioniert. Ich würde davon ausgehen, dies wäre in einem test-Projekt und als ein bonus, den Sie hätte der andere Test-Funktionen einmal hast du dieses setup. Wichtigste stören würde wahrscheinlich aussortieren der Abhängigkeit Kette.
Hier ist eine Klasse, ich schrieb dies für ASP.NETCore RC2. Ich benutze es so, ich kann html-E-Mail mit Razor.
Ich einen besseren Weg gefunden zu Rendern razor-Ansicht-Seite, wenn ich habe Fehler mit den oben genannten Methoden, ist diese Lösung für beide web-Formular Umwelt-und mvc-Umfeld.
Kein controller erforderlich ist.
Hier ist das code-Beispiel in diesem Beispiel habe ich exemplarisch ein mvc-Aktion mit einem async-http-handler: