2009-03-04 6 views
0

Ich möchte die WebFormViewEngine erweitern, so dass ich einige Nachbearbeitung durchführen kann - ich will es tun, es Zeug, dann gib mir die HTML zurück, so dass ich einige letzte Schliffe machen kann. Es muss als View/ViewEngine ausgeführt werden, da ich Zugriff auf die ViewData benötige.Erweitern von WebFormView in MVC

Leider scheint es keine Möglichkeit zu geben, den HTML-Code aus dem WebFormView zurückzuholen, und es gibt keine Möglichkeit, einen benutzerdefinierten HtmlTextWriter dem WebFormView oder ViewPage zu übergeben.

Sicher gibt es einen Weg, dies zu tun? Nein?

Littlecharva

Antwort

2

Sie können dazu Aktionsfilter verwenden. Überprüfen Sie this tutorial bei asp.net/mvc. Sie möchten einen ResultsFilter verwenden.

Als Alternative können Sie die virtuelle OnResultExecuted-Methode des Controllers überschreiben.

+0

Danke, das bringt mich ein bisschen näher zu dem, wo ich sein möchte. Ich kann natürlich erreichen, was ich mit Action Filters oder Override OnResultExecuted, aber ich fühle mich der Code, den ich schreibe gehört in eine ViewEngine, wie es auf allen Ansichten ausgeführt werden soll. – littlecharva

+0

Es kann auf allen Ansichten in dieser Anwendung ausgeführt werden, aber nicht in jeder Anwendung. Sie möchten nicht den Rahmen für jedes Projekt ändern. – Matthew

0

Okay, ich habe noch nie gemacht, aber ich sah durch Reflektor und der MVC Baugruppen. Es sieht so aus, als könnten Sie das ViewPage- und das ViewPage- und das ViewMasterPage-Objekt mit Ihrem Objekt erweitern. In Ihrem eigenen Objekt können Sie die Render-Methode überschreiben und ein Handle auf den HtmlTextWriter bekommen. Dann gib es einfach an die Basis weiter und lass es sein Ding machen. Etwas Ähnliches (das ist nicht getestet und nur theoretisch, es gibt möglicherweise mehr Methoden, die Sie außer Kraft setzen müssen.) Ich empfehle, Reflektoren zu verwenden, um zu sehen, wie es jetzt gemacht wird und wie andere View-Engines wie Spark es machen.

public class MyPage : ViewPage 
{ 
    protected override void Render(System.Web.UI.HtmlTextWriter writer) 
    { 
     //Do custom stuff here 
     base.Render(writer); 
    } 
} 
public class MyPage<TModel> : MyPage where TModel : class 
{ 
} 
+0

Ich hatte Reflektor verwendet und untersucht diese Route, das Problem ist, dass es scheint, keine Möglichkeit zu sein, die WebViewEngine meine ViewPage anstelle der Standard-instanziieren. Es scheint einen BuildManager zu verwenden, aber es gibt keine offensichtliche Möglichkeit, den BuildManager zu steuern. – littlecharva

1

Sie können den Ausgabeempfänger erfassen, bevor die Ansicht gerendert wird, indem Sie die Render-Methode der WebFormView-Klasse überschreiben. Der Trick besteht darin, dass der Ausgabeempfänger nicht der System.IO.TextWriter-Writer, sondern die Writer-Eigenschaft des viewContext ist. Außerdem müssen Sie WebFormViewEngine erweitern, um Ihre Ansichten zurückzugeben.

public class MyViewEngine : WebFormViewEngine 
{ 
    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 
    { 
     return new MyView(partialPath, null); 
    } 

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 
    { 
     return new MyView(viewPath, masterPath); 
    } 
}  

public class MyView : WebFormView 
{ 
    public MyView(string inViewPath, string inMasterPath) : base(inViewPath, inMasterPath) { } 
    public MyView(string inViewPath) : base(inViewPath) { } 

    public override void Render(ViewContext viewContext, System.IO.TextWriter writer) 
    { 
     //make a switch to custom output receiver 
     var oldWriter = viewContext.Writer; 
     viewContext.Writer = new System.IO.StringWriter(); 
     base.Render(viewContext, null); 
     viewContext.Writer.Close(); 

     //get output html 
     var html = ((System.IO.StringWriter)viewContext.Writer).GetStringBuilder(); 

     //perform processing 
     html.Replace('a', 'b'); 

     //retransmit output 
     viewContext.Writer = oldWriter; 
     viewContext.Writer.Write(html); 
    } 
}