2012-01-05 10 views
22

Sto cercando di utilizzare CDN per le mie immagini sul sito web. Il problema è che a volte ho controlli server come ImageButton e vorrei usare una classe per estrarre completamente il percorso della CDN. per quello scopo ho provato a fare:I tag del server non possono contenere i costrutti <% ... %>

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

e ottengo il titolo come errore.

Solo se sto usando <% # funzionerà (e solo se ho un collegamento dati). Come posso farlo facilmente? come posso inserire il codice CDN sul mio codice di markup?

Grazie!

risposta

23

Ci sono quattro opzioni (oltre al databinding di stile "<%# %>", che non rec ommend):

  1. Impostare il valore nel codice dietro. Questo gonfia ViewState e, naturalmente, richiede modifiche al codice per ogni istanza del controllo.
  2. Utilizzare un ExpressionBuilder personalizzato. Questo non gonfia ViewState, ma richiede la modifica di tutto il tuo markup.
  3. Utilizzare un adattatore di controllo per modificare il comportamento del controllo in qualsiasi punto della propria app; ad esempio, modificando la proprietà ImageUrl prima del rendering del controllo. Può essere fatto senza impatto di ViewState.
  4. Utilizzare una classe che eredita dalla classe ImageButton, combinata con la mappatura dei tag per utilizzare quella classe invece dell'originale in qualsiasi punto dell'app, ed eliminare la necessità di modifiche al markup. Può essere fatto senza impatto di ViewState.

L'opzione migliore dipende dai requisiti del vostro app, ma io di solito preferiscono un adattatore di controllo se si desidera apportare le modifiche a livello di sito.

Ecco un esempio, nel caso in cui aiuta:

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

Configura nella tua app con la seguente voce nel App_Browers/adattatore.Browser:

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

vostro codice sarebbe:

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

fresco, giusto ??

1

Naturalmente, la cosa migliore è quello di dare l'ImageButton un id, es:

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

E poi all'interno di caricamento della pagina assegnare l'Url:

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

Stavo pensando a qualcosa per evitare il CodeBehind – Himberjack

+2

Anche se questo approccio funzionerà, uno svantaggio è che aumenta anche la dimensione di ViewState (che non può essere disabilitato, dal momento che stai controllando! IsPostBack). – RickNZ

10

È possibile valutare il codice in un tag del server creando il proprio Code Expression Builder. È abbastanza semplice

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

E una voce nel web.config:

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

Questo consente di utilizzare una sintassi come ad esempio:

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

Ecco una spiegazione completa: http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx

+1

Grazie per il codice. Questo è esattamente quello che sto cercando. – Misha

19

Nel caso in cui qualcun altro incontri questo thread in futuro, è possibile ottenere il risultato richiesto circondando il tag del server con virgolette singole, anziché virgolette doppie.

L'originale:

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

La nuova versione:

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

Questo funziona in .Net 4.0, ma vorrei presumere che avrebbe funzionato nelle altre versioni anche.

+1

Avrei voluto passare più volte! –

+19

questo mostra solo il tag effettivo incluso il <% = nell'elemento per me –

Problemi correlati