Les balises du serveur ne peuvent pas contenir de constructions

j'essaie D'utiliser CDN pour mes images sur le site. Le problème est que, parfois, j'ai des commandes de serveur comme ImageButton, et j'aimerais utiliser une classe afin d'extraire complètement le chemin du CDN. pour cela j'ai essayé de faire:

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

et j'obtiens le titre de l'erreur.

seulement si j'utilise <%# cela fonctionnera (et seulement si j'utilise une banque de données). Comment puis-je faire cela facilement? Comment puis-je placer le code CDN sur mon code markup?

Merci!

22
demandé sur Himberjack 2012-01-05 09:34:05

4 réponses

Il y a quatre options (en plus de "<%# %>" style de la liaison de données, que je ne recommande pas):

  1. définir la valeur en code derrière. Cela gonfle ViewState, et bien sûr nécessite des changements de code pour chaque instance de la commande.
  2. utilisez un Impressionbuilder personnalisé. Cela ne gonfle pas ViewState, mais il ne nécessite de changer tout votre markup.
  3. utilisez un adaptateur de contrôle pour changer le comportement du contrôle partout dans votre application; par exemple, en modifiant la propriété ImageUrl avant que le contrôle ne soit rendu. Peut être fait sans impact visu-dessus.
  4. utilisez une classe qui hérite de la classe ImageButton, combinée avec tag mapping pour utiliser cette classe au lieu de l'original partout dans votre application, et éliminez la nécessité de modifier votre markup. Peut être fait sans impact visu-dessus.

la meilleure option dépend des exigences de votre application, mais je préfère généralement un adaptateur de contrôle si vous voulez faire le les changements à l'échelle du site.

voici un exemple, au cas où cela aiderait:

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

Configurer votre application avec l'entrée suivante dans App_Browers/adaptateur.navigateur:

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

Votre balisage serait:

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

Cool, non??

23
répondu RickNZ 2012-01-06 00:00:16

dans le cas où quelqu'un d'autre croise ce fil dans le futur, vous pouvez obtenir le résultat requis en entourant la balise du serveur avec des guillemets simples, plutôt que des guillemets doubles.

origine:

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

La nouvelle version:

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

cela fonctionne dans .Net 4.0, mais je suppose que cela fonctionnerait aussi dans les autres versions.

21
répondu Nick 2014-04-29 09:55:09

vous pouvez évaluer le code dans une étiquette de serveur en créant votre propre constructeur D'expressions de Code. C'est assez simple.

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

et une entrée dans votre web.config:

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

Cela vous permet d'utiliser une syntaxe telle que:

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

Voici une explication complète: http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx

12
répondu Tim Medora 2012-01-05 06:32:53

bien sûr, votre meilleur pari est de donner à l'imagebutton un identifiant, par exemple:

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

et puis dans votre chargement de page assignez l'imageurl:

void Page_Load(...)
{
     if (!Page.IsPostback)
     {
          IAgreeImageButton.ImageUrl = ResourceManager.GetImageCDN("iagree.png");
     }
}
1
répondu Rocklan 2012-01-05 05:44:59