在此例中,新前缀为“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;
}