WebResource を aspx/ascx に埋め込む Expression
id:ladybug:20060316#p1 の内容を ExpressionBuilder にまとめました。
- ソースコードを使用したい Web Application に取り込みます。
- 使用したい Web Application の web.config にエントリを追加します。
- aspx/aspcx で設定した prefix を指定した Expression 式を記述する
例:
<asp:Image ID="Image1" runat="server" ImageUrl="<%$WebResource: ImageKit, Logo.gif %>" />
と書くと、ImageKit 型を含むアセンブリの Logo.gif という埋め込みリソースを取得する WebResource URL に置き換わります。
使用したい Web Application の web.config にエントリを追加
<configuration> <system.web> <compilation debug="false"> <expressionBuilders> <add expressionPrefix="WebResource" type="Lx.Web.Compilation.WebResourceExpressionBuilder"/> </expressionBuilders> </compilation> </system.web> </configuration>
expressionPrefix は aspx/ascx の中で記述する <%$ xxxx %> の xxxx の部分です。省略するとソースコード側に設定された値 WebResource になります。
type は ExpressionBuilder を実装したクラス名なので、この日記に記載されたソースコードを使用する場合は上記の通りです。
ソース
// code formatted by http://manoli.net/csharpformat/ using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.Compilation; using System.CodeDom; using System.Reflection; using System.Diagnostics; namespace Lx.Web.Compilation { /// <summary> /// ResourceExpressionBuilder クラスは、ページの実行時に埋め込み Web リソースを取得する URL を作成します。 /// 埋め込み Web リソースには特定の言語またはカルチャにローカライズされた情報を含めることができません。 /// </summary> [ExpressionPrefix("WebResource")] public class WebResourceExpressionBuilder : ExpressionBuilder { public WebResourceExpressionBuilder() { } /// <summary> /// コンパイルなしページをサポートするか /// </summary> public override bool SupportsEvaluate { // TODO: 実行時評価を実装してサポートする get { return false; } } /// <summary> /// 文字列形式の式を解析し、式を表すオブジェクトを返します。 /// </summary> public override object ParseExpression(string expression, Type propertyType, ExpressionBuilderContext context) { // <%$ WebResource: TypeName, ResourceName %> string[] args = expression.Split(','); if (args.Length != 2) { throw new HttpException( "引数が不正です。グローバルリソースファイル名, キー名 形式である必要があります。: " + expression); } else { try { // TODO: リソースの存在チェックを実施し、存在しないリソースの場合にエラーとする return new ResourcesEntry(args[0].Trim(), args[1].Trim()); } catch (ArgumentException e) { throw new HttpException( "引数が不正です。グローバルリソースファイル名, キー名 形式である必要があります。: " + expression, e); } } } public class ResourcesEntry { public ResourcesEntry(string typename, string resname) { if (string.IsNullOrEmpty(typename)) throw new ArgumentNullException("typename", "リソースのファイル名が指定されていません。"); if (string.IsNullOrEmpty(resname)) throw new ArgumentNullException("resname", "リソースのキー名が指定されていません。"); this.TypeName = typename; this.ResourceName = resname; } public readonly string TypeName; public readonly string ResourceName; } /// <summary> /// 式を表すオブジェクトをページ実行中に使用されるコードへ変換する /// </summary> public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { ResourcesEntry resent = parsedData as ResourcesEntry; Debug.Assert(resent != null, "aye?"); // target = this.ClientScript CodeExpression target = new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), "ClientScript"); // target.GetWebResourceUrl(typeof(resent.TypeName), resent.ResourceName) return new CodeMethodInvokeExpression( target, "GetWebResourceUrl", new CodeTypeOfExpression(resent.TypeName), new CodePrimitiveExpression(resent.ResourceName)); } } }