Подтвердить что ты не робот

Теги сервера не могут содержать конструкторы <%...%>

Я пытаюсь использовать CDN для своих изображений на веб-сайте. Проблема в том, что иногда у меня есть серверные элементы управления, такие как ImageButton, и я хотел бы использовать класс для полного извлечения пути CDN. для этого я попытался сделать:

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

и я получаю заголовок как ошибку.

Только если я использую <% #, он будет работать (и только если я привязываю данные). Как я могу сделать это легко? как я могу поместить код CDN в свой код разметки?

Спасибо!

4b9b3361

Ответ 1

Существует четыре варианта (помимо привязки "<%# %>" стиля, которые я не рекомендую):

  • Задайте значение в коде. Это раздувает ViewState и, конечно, требует изменений кода для каждого экземпляра элемента управления.
  • Используйте специальный ExpressionBuilder. Это не раздувает ViewState, но требует изменения всей вашей разметки.
  • Используйте адаптер управления, чтобы изменить поведение элемента управления повсюду в вашем приложении; например, путем изменения свойства ImageUrl перед визуализацией элемента управления. Может быть сделано без влияния ViewState.
  • Используйте класс, который наследуется от класса 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

Вы можете оценить код в теге сервера, создав свой собственный Code Expression Builder. Это довольно просто.

[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

Конечно, ваш лучший выбор - дать идентификатору изображения идентификатор, например:

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

И затем в вашей загрузке страницы назначьте imageurl:

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