【问题标题】:Server tags cannot contain <% ... %> constructs服务器标签不能包含 <% ... %> 结构
【发布时间】:2012-01-05 05:34:05
【问题描述】:

我正在尝试对网站上的图片使用 CDN。 问题是,有时我有ImageButton之类的服务器控件,我想使用一个类来完全提取CDN的路径。为此,我尝试这样做:

<asp:ImageButton runat="server" OnClick="Agree" ImageUrl="<%=ResourceManager.GetImageCDN("iagree.png")%>" />

我得到的标题是错误的。

仅当我使用

谢谢!

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    有四个选项(除了“&lt;%# %&gt;”样式数据绑定,我不推荐):

    1. 在后面的代码中设置值。这会使 ViewState 膨胀,当然需要对控件的每个实例进行代码更改。
    2. 使用自定义 ExpressionBuilder。这不会夸大 ViewState,但确实需要更改所有标记。
    3. 使用控件适配器更改应用程序中各处的控件行为;例如,通过在呈现控件之前修改 ImageUrl 属性。可以在不影响 ViewState 的情况下完成。
    4. 使用继承自 ImageButton 类的类,并结合标记映射使用该类而不是应用程序中的原始类,并且无需更改标记。可以在不影响 ViewState 的情况下完成。

    最佳选择取决于您应用的要求,但如果您想在整个站点范围内进行更改,我通常更喜欢控制适配器。

    这是一个例子,以防有帮助:

    using System;
    using System.IO;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.Adapters;
    
    namespace Sample
    {
        public class ImageButtonControlAdapter : WebControlAdapter
        {
            protected override void BeginRender(HtmlTextWriter writer)
            {
                ImageButton image = this.Control as ImageButton;
                if ((image != null) && !String.IsNullOrEmpty(image.ImageUrl))
                {
                    //
                    // Decide here which objects you want to change
                    //
                    if (!image.ImageUrl.StartsWith("http") && 
                        !image.ImageUrl.StartsWith("data:"))
                    {
                        image.ImageUrl = ResourceManager.GetImageCDN(image.ImageUrl);
                    }
                }
                base.BeginRender(writer);
            }
        }
    }
    

    使用 App_Browers/adapter.browser 中的以下条目将其配置到您的应用中:

    <browsers>
      <browser refID="Default">
        <controlAdapters>
          <adapter controlType="System.Web.UI.WebControls.ImageButton"
                   adapterType="Sample.ImageButtonControlAdapter" />
        </controlAdapters>
      </browser>
    </browsers>
    

    您的标记将是:

    <asp:ImageButton runat="server" OnClick="Agree" ImageUrl="iagree.png" />
    

    很酷,对吧??

    【讨论】:

      【解决方案2】:

      如果其他人将来遇到此线程,您可以通过用单引号而不是双引号将服务器标记括起来来获得所需的结果。

      原文:

      <asp:ImageButton runat="server" OnClick="Agree" ImageUrl="<%=ResourceManager.GetImageCDN("iagree.png")%>" />
      

      新版本:

      <asp:ImageButton runat="server" OnClick="Agree" ImageUrl='<%=ResourceManager.GetImageCDN("iagree.png")%>' />
      

      这适用于 .Net 4.0,但我认为它也适用于其他版本。

      【讨论】:

      • 这只是为我输出包含
      【解决方案3】:

      您可以通过创建自己的代码表达式生成器来评估服务器标记中的代码。这很简单。

      [ExpressionPrefix( "Code" )]
      public class CodeExpressionBuilder : ExpressionBuilder
      {
          public override CodeExpression GetCodeExpression( BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context )
          {
              return new CodeSnippetExpression( entry.Expression );
          }
      }
      

      在您的 web.config 中添加一个条目:

      <compilation debug="true" targetFramework="4.0">
          <expressionBuilders>
              <add expressionPrefix="Code" type="[YourNamespace].CodeExpressionBuilder"/>
          </expressionBuilders>
      </compilation>
      

      这允许您使用如下语法:

      <asp:ImageButton runat="server" ImageUrl='<%$ Code:ResourceManager.GetImageCDN("iagree.png") %>'>
      

      这里有完整的解释:http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx

      【讨论】:

        【解决方案4】:

        当然,最好的办法是给 imagebutton 一个 id,例如:

        <asp:ImageButton id="IAgreeImageButton" runat="server" Onclick="Agree" />
        

        然后在您的页面加载中分配 imageurl:

        void Page_Load(...)
        {
             if (!Page.IsPostback)
             {
                  IAgreeImageButton.ImageUrl = ResourceManager.GetImageCDN("iagree.png");
             }
        }
        

        【讨论】:

        • 我在想办法避免 CodeBehind
        • 虽然这种方法可行,但一个缺点是它也会增加 ViewState 的大小(无法禁用,因为您正在检查 !IsPostBack)。
        猜你喜欢
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-03
        • 2012-01-13
        相关资源
        最近更新 更多