问题描述
我需要使用的appSettings
定义的应用程序上下文来获取本地资源:
I need to retrieve local resources using an application context defined in appSettings
:
<add key="ApplicationContext" value="CTX1"/>
这也可与另一个值部署:
which could also be deployed with another value:
<add key="ApplicationContext" value="CTX2"/>
和这样定义的本地资源:
and define local resources like this:
<root>
<data name="CTX1_BodyTitle1" xml:space="preserve">
<value>Welcome to context 1</value>
</data>
<data name="CTX2_BodyTitle1" xml:space="preserve">
<value>Welcome to context 2</value>
</data>
<root>
然后aspx页面使用隐式资源名称:
then use implicit resource name in aspx page:
<h2><asp:Literal runat="server" meta:ressourcekey="BodyTitle1"></asp:Literal></h2>
我想实现一个自定义ResourceProvider在而是告诉没有设法做一些有效的,也不简单。
I tried to implement a custom ResourceProvider as told on msdn but did not manage to do something effective nor simple.
不知道如何privide这一点没有重新实现整个?
Any idea how to privide this without reimplementing the whole ResourceProviderFactory
?
编辑:
我要含蓄检索本地从 Page1.en.resx
, Page1.fr.resx 资源code>根据ApplicationContext中,然后使用一个唯一的标识符
Page1.aspx的
链接到定义的资源。
I want to implicitly retrieve local resources from Page1.en.resx
, Page1.fr.resx
according to ApplicationContext, then use an unique identifier in Page1.aspx
to link to defined resources.
推荐答案
据@BartoszKP的意见,我写了一个自定义的防爆pressionBuilder
是考虑到acount的ApplicationContext和本地化(在比拉勒·海达尔基地):
According to @BartoszKP advice, I wrote a custom ExpressionBuilder
that takes into acount ApplicationContext and localization (base on a Bilal Haidar article):
的Web.config有权宣布它:
Web.config has to declare it :
<system.web>
<expressionBuilders>
<add expressionPrefix="Contextual" type="SinsedrixLibrary.ContextualExpressionBuilder"/>
</expressionBuilders>
</system.web>
和aspx页面就必须要求的ressource使用preFIX:
And aspx page just have to request ressource with a prefix:
<h1><asp:Literal runat="server" Text='<%$ Contextual: LitWelcome %>'></asp:Literal></h1>
下面是防爆pressionBuilder
:
namespace SinsedrixLibrary
{
/// <summary>
/// This source file includes the source code for the
/// XmlSettingExpressionBuilder, which is used to handle
/// declarative expressions based on an XML settings file.
/// </summary>
public class ContextualExpressionBuilder : ExpressionBuilder
{
public ContextualExpressionBuilder()
{ }
/// <summary>
/// This method will be called during page execution
/// to get the expression that is going to be executed
/// to return the value of the declarative expression
/// </summary>
/// <param name="entry"></param>
/// <param name="parsedData"></param>
/// <param name="context"></param>
/// <returns></returns>
public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
{
// Get a reference to this class since we are going to
// execute a method on this class that will evaluate
// the required expression
CodeTypeReferenceExpression thisType = new CodeTypeReferenceExpression(base.GetType());
// Create a new expression based on the KEY specified
// in the declarative expression, this will be used
// as an input to the method that will evaluate the
// required expression
CodePrimitiveExpression expression = new CodePrimitiveExpression(entry.Expression.Trim().ToString());
string l_resxPath = Path.GetDirectoryName(context.VirtualPath) + "\\App_LocalResources\\"+ Path.GetFileName(context.VirtualPath);
CodePrimitiveExpression resxPath = new CodePrimitiveExpression(l_resxPath);
// The static method name that will evaluate the
// expression, by accessing the XML file and retreiving
// the value that corresponds to the key specified
string evaluationMethod = "GetContextResource";
// Finally, return the expression that will invoke the method
// responsible for evaluating the expression
// The CodeMethodInvokeExpression takes as input the type on which to execute the method specified,
// the method name, and the array of CodeExpression, which represents the parameters of the method called
return new CodeMethodInvokeExpression(thisType, evaluationMethod, new CodeExpression[] { expression, resxPath });
}
/// <summary>
/// Evaluates the expression by accessing the XMLSettings file
/// and retrieve the value corresponding to the key specified in
/// the input expression.
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public static string GetContextResource(string expression, string resxPath)
{
// Get the XML Setting file from the application cache if present
CultureInfo ci = CultureInfo.CurrentCulture;
string resxKey = resxPath + "." + ci.TwoLetterISOLanguageName;
XmlDocument xmlSettingDoc = (XmlDocument)HostingEnvironment.Cache[resxKey];
// check if there was an already loaded document
if (xmlSettingDoc == null)
{
// Define the document here
xmlSettingDoc = new XmlDocument();
// Get the config file path using the HostingEnvironment
// which gives information for application-specific
string resxCultureFile = resxKey + ".resx";
string resxDefaultFile = resxPath + ".resx";
string resxFile = "";
try
{
resxFile = HostingEnvironment.MapPath(resxCultureFile);
}
catch(Exception) {
resxFile = HostingEnvironment.MapPath(resxDefaultFile);
}
// Load the XML file into the XmlDocument
xmlSettingDoc.Load(resxFile);
// Create a new file dependency to be used when we add the XmlDocument
// into the Cache, so that when the XmlSettings file change, the Cache will
// be invalid.
CacheDependency settingsDepend = new CacheDependency(resxFile);
// Add the Xmldocument to the Cache
HostingEnvironment.Cache.Insert(resxKey, xmlSettingDoc, settingsDepend);
}
string ctx = ConfigurationManager.AppSettings["ApplicativeContext"];
// XPATH key used to retrieve the record needed in the form of add[@key='keyvalue']
string getXPATHKey = String.Format("//data[@name='{0}_{1}']/value", ctx, expression);
// Search for that record
XmlNode wantedRecord = xmlSettingDoc.SelectSingleNode(getXPATHKey);
// If the record exists, return the value property
if (wantedRecord != null)
return wantedRecord.InnerText;
// return a message informing users that the expression failed to
// evaluate to a real value
return string.Format("Unable to Process Expression : '{0}'", expression);
}
}
}
这篇关于重写默认ResourceProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!