2013-10-15 88 views
0

我需要使用appSettings定義的應用程序上下文檢索本地資源:重寫默認ResourceProvider

<add key="ApplicationContext" value="CTX2"/> 

,並確定本地資源是這樣的:這也可以與另一個值部署

<add key="ApplicationContext" value="CTX1"/> 

<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> 

然後在asp中使用隱式資源名X頁:

<h2><asp:Literal runat="server" meta:ressourcekey="BodyTitle1"></asp:Literal></h2> 

我試圖實現一個自定義ResourceProvider所講述的msdn但沒有設法做一些有效的,也不簡單。

任何想法如何在不重新實現整個ResourceProviderFactory的私密性?

編輯:

我想根據從ApplicationContext的Page1.en.resxPage1.fr.resx隱含檢索當地資源,然後使用一個唯一的標識符Page1.aspx鏈接到定義的資源。

回答

1

據@BartoszKP意見,我寫了一個定製ExpressionBuilder是考慮到acount的ApplicationContext和本地化(底座上的比拉爾·海達爾article):

網絡。配置有權宣佈它:

<system.web> 
    <expressionBuilders> 
     <add expressionPrefix="Contextual" type="SinsedrixLibrary.ContextualExpressionBuilder"/> 
    </expressionBuilders> 
</system.web> 

而且aspx頁面就必須要求的ressource用一個前綴:

<h1><asp:Literal runat="server" Text='<%$ Contextual: LitWelcome %>'></asp:Literal></h1> 

這裏是ExpressionBuilder

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

至於我關心有簡單的方法來做到這一點,但讓我分享,我想可以幫你

創建一個類,您可以訪問webconfing或AppConfig的文件類似下面

public static class appdata 
{ 

    static ResourceManager rm = new ResourceManager("Resources.Resource", System.Reflection.Assembly.Load("App_GlobalResources")); 
static  CultureInfo ci = default(CultureInfo); 


    private static isValidChassisTableAdapter _isvalidchassis = null; 
    private static SG_FORMTableAdapter _sgform = null; 
    private static settingTableAdapter _setting = null; 
    private static IsInRoleTableAdapter _Role = null; 
    private static tblaccountsTableAdapter _accounts = null; 
    private static tblloginhistoryTableAdapter _AppEvents = null; 

    private static configTableAdapter _AppConfig = null; 
    public static configTableAdapter AppConfig 
    { 
     get 
     { 
      if (_AppConfig == null) 
      { 
       _AppConfig = new configTableAdapter(); 
      } 

      return _AppConfig; 
     } 
    } 
public static string ApplicationContext 
    { 
     get { return ConfigurationManager.AppSettings.Get("ApplicationContext"); } 
    } 
} 

然後用它在aspx頁面像這樣

<h2><%=appdata.ApplicationContext%></h2> 
+0

我知道了如何獲取的ApplicationContext – sinsedrix

0

在應用程序中我的團隊開發的,我們首先創建一個繼承OverridenResourceManager處理這ResourceManager中(在System.Resources) 示例代碼提供如下:

/// <summary> 
/// Resource manager that uses resources found in the exceptions folder before falling back to the built-in resource file. 
/// </summary> 
public class OverridenResourceManager : ResourceManager 
{ 

    #region Constructors and Destructors 

    /// <summary> 
    /// Initializes a new instance of the <see cref="OverridenResourceManager "/>lass. 
    /// </summary> 
    /// <param name="name"> 
    /// The name of the resource file. 
    /// </param> 
    /// <param name="culture"> 
    /// The string culture to find resources for. 
    /// </param> 
    public OverridenResourceManager(string name, Assembly culture) 
     : base(name, culture) 
    { 
     this.Name = name.Replace("AssemblyName.Localization.", string.Empty); 
    } 

    #endregion 

    #region Public Properties 

    /// <summary> 
    /// Gets or sets a function that return a dictionary of overrides for the currentsite 
    /// </summary> 
    public static Func<Dictionary<string, string>> TextOverridesDictionary { get; set;} 

    /// <summary> 
    /// Gets or sets the name of the resources class to handle. 
    /// </summary> 
    public string Name { get; set; } 

    #endregion 

    #region Public Methods and Operators 

    /// <summary> 
    /// Gets the resource named <paramref name="name"/> for the given <paramref name="culture"/>. 
    /// Tries to use the value in an exceptions file (through a pre-built dictionary), if any, 
    /// otherwise uses the built-in method. 
    /// </summary> 
    /// <param name="name"> 
    /// The name of the resource to get. 
    /// </param> 
    /// <param name="culture"> 
    /// The string culture to get the resource for. 
    /// </param> 
    /// <returns> 
    /// The <see cref="string"/> containing the value of the resource. 
    /// </returns> 
    public override string GetString(string name, CultureInfo culture) 
    { 
     if (TextOverridesDictionary != null) 
     { 
      // As we are only giving one file we need to fully qualify the name we are looking for 
      var resourceName = this.Name + '.' + name; 

      // TextOverridesDictionary contains a closure to get the dictionary 
      // from the session's website configuration object 
      var overrides = TextOverridesDictionary(); 
      if (overrides != null && overrides.ContainsKey(resourceName)) 
      { 
       return overrides[resourceName]; 
      } 
     } 

     return base.GetString(name, culture); 
    } 
} 

當應用程序啓動,我們然後 設置

TextOverridesDictionary =() => Session.Site.TextResourceOverrides; 

其中在短調用抓住字典鍵/值的方法提供的一對資源。你需要實現一個方法,從你的.config文件中抓取正確的鍵/值,這非常簡單。如果需要,我可以提供示例代碼。

有了這個OverridenResourceManager,我們會檢查同一個命名空間中的任何資源,比如我們的「AssemblyName.Localization」,然後檢查現有的資源。

+0

你在哪裏考慮到ApplicationContext?你在哪裏設置新的ResourceManager而不是默認的? – sinsedrix