2012-01-05 45 views
22

Estoy tratando de usar CDN para mis imágenes en el sitio web. El problema es que a veces tengo controles de servidor como ImageButton, y me gustaría utilizar una clase para extraer completamente la ruta de la CDN. para ese fin intenté hacer:Las etiquetas de servidor no pueden contener construcciones <% ... %>

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

y obtengo el título como error.

Solo si estoy usando <% # funcionará (y solo si tengo un enlace de datos). ¿Cómo puedo hacer esto fácilmente? ¿Cómo puedo colocar el código CDN en mi código de marcado?

Gracias!

Respuesta

23

Hay cuatro opciones (además del enlace de datos "<%# %>", que no recomiendo recomendación):

  1. Establezca el valor en el código detrás. Esto infla ViewState y, por supuesto, requiere cambios de código para cada instancia del control.
  2. Utilice un ExpressionBuilder personalizado. Esto no infle ViewState, pero requiere cambiar todo su marcado.
  3. Use un Adaptador de control para cambiar el comportamiento del control en todas partes de su aplicación; por ejemplo, modificando la propiedad ImageUrl antes de que se represente el control. Se puede hacer sin impacto en ViewState.
  4. Utilice una clase heredada de la clase ImageButton, combinada con la asignación de etiquetas para usar esa clase en lugar del original en todas partes de la aplicación, y elimine la necesidad de realizar cambios en su marcado. Se puede hacer sin impacto en ViewState.

La mejor opción depende de los requisitos de su aplicación, pero generalmente prefiero un adaptador de control si desea realizar los cambios en todo el sitio.

He aquí un ejemplo, en el caso de que ayuda:

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); 
     } 
    } 
} 

Configurar en su aplicación con la siguiente entrada en App_Browers/adaptador.navegador:

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

su margen de beneficio sería:

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

frío, ¿no ??

1

Por supuesto, lo mejor es dar al ImageButton un id, por ejemplo:

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

Y luego dentro de su carga de la página asignar el ImageUrl:

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

Estaba pensando en algo para evitar el CodeBehind – Himberjack

+2

Aunque este enfoque funcionará, un inconveniente es que también aumenta el tamaño de ViewState (que no se puede deshabilitar, ya que está buscando! IsPostBack). – RickNZ

10

Usted puede evaluar código en una etiqueta del servidor creando su propio Generador de expresiones de código. Es bastante simple.

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

Y una entrada en su web.config:

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

Esto le permite utilizar una sintaxis como:

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

He aquí una explicación completa: http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx

+1

Gracias por el código. Eso es exactamente lo que estoy buscando. – Misha

19

En caso de que alguien más se encuentre con este hilo en el futuro, puede obtener el resultado requerido rodeando la etiqueta del servidor con comillas simples, en lugar de comillas dobles.

El original:

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

La nueva versión:

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

Esto funciona en .Net 4.0, pero yo presumiría que trabajaría en las otras versiones también.

+1

¡Me hubiera gustado votar muchas veces! –

+19

esto solo muestra la etiqueta actual incluyendo el <% = en el elemento para mí –

Cuestiones relacionadas