在此例中,新前綴為“ExternalResource”。此新表達式的所需語法如下所示。
<%$ ExternalResource: [assemblyName]|[resourceType], [resourceKey] %>
此表達式將使用先前介紹的同一 GlobalExternalResourceProvider 從特定程序集提取資源。為支持這一新表達式,我們將創建一個自定義類型 ExternalResourceExpressionBuilder。表 2 總結了由每個替換的 ExpressionBuilder 方法所提供的功能。
表 2 總結了由每個替換方法所提供的功能
方法 說明 EvaluateExpression 在未編譯頁面中返回 ExternalResource 表達式的資源值。 GetCodeExpression 返回為 ExternalResource 表達式生成的代碼。此代碼將調用自定義資源提供程序 GlobalExternalResourceProvider。 ParseExpression 通過嘗試訪問表達式資源來驗證 ExternalResource 表達式。如果無法找到資源,頁面分析將失敗。 SupportsEvaluate 屬性 指示是否支持未編譯頁面判斷。在此實現中,將返回 true。使用 ExternalResourceExpressionBuilder,可聲明如下所示的自定義本地化表達式。
<asp:Label ID="labExternalResource" runat="server" Text="<%$ ExternalResources:CommonResources|CommonTerms, Hello %>" meta:localize="false" ></asp:Label>
請記住,表達式在設計時並且在編譯前進行分析。在頁面分析期間會調用 ParseExpression,以驗證資源表達式是否准確以及請求的資源是否實際存在。以下代碼說明了此實現。
public override object ParseExpression(string expression, Type propertyType, ExpressionBuilderContext context)
{
if (string.IsNullOrEmpty(expression))
{
throw new ArgumentException(String.Format(Thread.CurrentThread.CurrentUICulture,Properties.Resources.Expression_TooFewParameters, expression));
}
ExternalResourceExpressionFields fields = null;
string classKey = null;
string resourceKey = null;
string[] expParams = expression.Split(new char[] { ',' });
if (expParams.Length > 2)
{
throw new ArgumentException(String.Format(Thread.CurrentThread.CurrentUICulture, Properties.Resources.Expression_TooManyParameters, expression));
}
if (expParams.Length == 1)
{
throw new ArgumentException(String.Format(Thread.CurrentThread.CurrentUICulture, Properties.Resources.Expression_TooFewParameters, expression));
}
else
{
classKey = expParams[0].Trim();
resourceKey = expParams[1].Trim();
}
fields = new ExternalResourceExpressionFields(classKey, resourceKey);
ExternalResourceExpressionBuilder.EnsureResourceProviderFactory();
IResourceProvider rp = ExternalResourceExpressionBuilder.
s_resourceProviderFactory.CreateGlobalResourceProvider(fields.ClassKey);
object res = rp.GetObject(fields.ResourceKey, CultureInfo.InvariantCulture);
if (res == null)
{
throw new ArgumentException(String.Format(Thread.CurrentThread.CurrentUICulture, Properties.Resources.RM_ResourceNotFound, fields.ResourceKey));
}
return fields;
}