捕获内联表达式结果

发布于 2024-09-24 03:58:37 字数 2088 浏览 2 评论 0原文

我需要做的是捕获 MVC 视图中表达式的结果(下面的示例)。

我还提供了一个存根处理器来演示我想要实现的目标。基本上我想将操作的目标转移到某个任意字符串缓冲区中,以便稍后进行操作。但是 Target 属性是只读的。可以像我下面所做的那样使用反射来覆盖它(将目标设置为以 StringBuffer 为核心的任意编写器)。这不能正常工作,并且当我执行 inline() 时,我不断收到空引用异常。

有人可以帮忙吗?下面的代码(GetInlineResult 是关键方法)。

查看

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% MvcApplication5.Processor.Absorb(() => {%>     
        reverse = (string) ->
          string.split('').reverse().join ''

        alert reverse '.eeffoC yrT'
    <%}); %>
    <%=MvcApplication5.Processor.Render()%>
</asp:Content>

处理器代码

public class Processor
{
    public static void Absorb(Action inline)
    {
        string input = GetInlineResult(inline);
        string output = Process(input);
        File.WriteAllText("SOME_PATH", output);  
    }

    private static string Process(string input)
    {
        string output = input;
        /* IRRELEVANT PROCESSING */
        return output;
    }

    private static string GetInlineResult(Action inline)
    {
        // create writers etc.
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        HtmlTextWriter htmltw = new HtmlTextWriter(sw);

        // set internal value to new writer
        FieldInfo fi = inline.GetType().GetField("_target", BindingFlags.Instance | BindingFlags.NonPublic);
        fi.SetValue(inline, htmltw);

        // execute 
        inline();

        // get contents
        return sb.ToString();
    }

    public static string Render()
    {
        /* GENERATE LINK TO RENDERED FILE <script type="tpl" src="SOME_PATH"> */
        return "<script type='tpl' src='SOME_URL'></script>";
    }
}

What I need to do is capture the result of an expression within an MVC view (sample below).

I have also provided a stub Processor demonstrating what I want to achieve. Basically I want to divert the Target of the Action into some arbitrary string buffer that I can manipulate later. However the Target property is readonly. Can this be overridden using reflection as I am doing below (setting the target to an arbitrary writer with a StringBuffer at its core). This doesn;t work correctly and I keep getting a Null Reference exception when I execute inline().

Can anyone help? Code below (GetInlineResult being the key method).

View

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% MvcApplication5.Processor.Absorb(() => {%>     
        reverse = (string) ->
          string.split('').reverse().join ''

        alert reverse '.eeffoC yrT'
    <%}); %>
    <%=MvcApplication5.Processor.Render()%>
</asp:Content>

Processor Code

public class Processor
{
    public static void Absorb(Action inline)
    {
        string input = GetInlineResult(inline);
        string output = Process(input);
        File.WriteAllText("SOME_PATH", output);  
    }

    private static string Process(string input)
    {
        string output = input;
        /* IRRELEVANT PROCESSING */
        return output;
    }

    private static string GetInlineResult(Action inline)
    {
        // create writers etc.
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        HtmlTextWriter htmltw = new HtmlTextWriter(sw);

        // set internal value to new writer
        FieldInfo fi = inline.GetType().GetField("_target", BindingFlags.Instance | BindingFlags.NonPublic);
        fi.SetValue(inline, htmltw);

        // execute 
        inline();

        // get contents
        return sb.ToString();
    }

    public static string Render()
    {
        /* GENERATE LINK TO RENDERED FILE <script type="tpl" src="SOME_PATH"> */
        return "<script type='tpl' src='SOME_URL'></script>";
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

锦爱 2024-10-01 03:58:37

问题解决了。

我过度思考这个问题并用文本编写器替换生成的视图类,而不是替换视图 TextWriter 实例。

更新了 GetInlineResult(目前处于非常粗糙的形式)

    private static string GetInlineResult(Action inline)
    {
        // create writers etc.
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        HtmlTextWriter htmltw = new HtmlTextWriter(sw);


        object view = inline.Target;
        FieldInfo field = view.GetType().GetField("__w");
        HtmlTextWriter tw = field.GetValue(view) as HtmlTextWriter;

        field.SetValue(view, htmltw);
        // execute 
        inline();

        field.SetValue(view, tw);

        // get contents
        return sb.ToString();
    }

Problem solved.

I was overthinking this problem and replacing the generated view class with a text writer rather than replacing the views TextWriter instance.

Updated GetInlineResult (currently in VERY crude form)

    private static string GetInlineResult(Action inline)
    {
        // create writers etc.
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        HtmlTextWriter htmltw = new HtmlTextWriter(sw);


        object view = inline.Target;
        FieldInfo field = view.GetType().GetField("__w");
        HtmlTextWriter tw = field.GetValue(view) as HtmlTextWriter;

        field.SetValue(view, htmltw);
        // execute 
        inline();

        field.SetValue(view, tw);

        // get contents
        return sb.ToString();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文