服务器标记不能包含<;%.%>;构造

本文关键字:gt 构造 lt 包含 服务器 不能 | 更新日期: 2023-09-27 18:19:33

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

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

我得到的标题是错误的。

仅当我使用<%#它将工作(并且只有当我有数据绑定时)。我怎样才能轻松做到这一点?如何在标记代码上放置CDN代码?

谢谢!

服务器标记不能包含<;%.%>;构造

有四个选项(除了我不推荐的"<%# %>"风格的数据绑定):

  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.brower中使用以下条目将其配置到您的应用程序中:

<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" />

很酷,对吧??

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

原件:

<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中有效,但我认为它在其他版本中也有效。

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

[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

当然,您最好的选择是给图像按钮一个id,例如:

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

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

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