2017-05-04 19 views
0

我正在嘗試編寫自定義表達式來將翻譯註入到網頁中,但我在運行時遇到了評估問題,因爲它僅在頁面啓動後才評估一次,而不是刷新或語言改變。我的代碼:自定義ExpressionBuilder翻譯和注入項目到佔位符僅被評估一次

<h2 style="margin-top:0px"><asp:Literal ID="Literal15" runat="server" Text="<%$ Translate:ChooseADataset %>"></asp:Literal></h2>

using System; 
    using System.CodeDom; 
    using System.Globalization; 
    using System.Linq; 
    using System.Text.RegularExpressions; 
    using System.Web; 
    using System.Web.Compilation; 
    using System.Web.UI; 

    [ExpressionPrefix("Translate")] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] 
    public class TranslationExpressionBuilder : ExpressionBuilder 
    { 
     public override bool SupportsEvaluate 
     { 
      get 
      { 
       return true; 
      } 
     } 

     public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) 
     { 
      return new CodePrimitiveExpression((string)parsedData); 
     } 

     public override object EvaluateExpression(object target, BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) 
     { 
      return TranslateAndFill((string)parsedData); 
     } 
     public override object ParseExpression(string expression, Type propertyType, ExpressionBuilderContext context) 
     { 
      bool parsed = false; 
      string typeName = null; 
      string memberName = null; 
      if (!String.IsNullOrEmpty(expression)) 
      { 
       var parts = expression.Split(',').ToList(); 

       if (parts.Count == 1) 
       { 
        memberName = parts[0].Trim(); 
       } 
       else if (parts.Count == 2) 
       { 
        typeName = parts[0].Trim(); 
        memberName = parts[1].Trim(); 
       } 

       parsed = true; 
      } 

      if (!parsed) 
      { 
       throw new HttpException("Invalid Reflect" + $" expression - '{expression}'."); 
      } 

      return TranslateAndFill(memberName); 
     } 

     private string TranslateAndFill(string name) 
     { 
      CultureInfo sCulture = WebHelpers.GetCurrentCultureInfo(); 

      var manager = new System.Resources.ResourceManager("Resources.String", 
       global::System.Reflection.Assembly.Load("App_GlobalResources")); 
      Regex regexp = new Regex("(?:\\[_)(?:.*)(?:_\\])", RegexOptions.Singleline); 
      var text = manager.GetString(name, sCulture); 
      var result = text; 

      var shortCircuit = false; 
      if (!string.IsNullOrEmpty(text)) 
      { 
       var matches = regexp.Matches(text); 
       while (matches.Count != 0 && shortCircuit == false) 
       { 
        foreach (var match in matches) 
        { 
         var key = match.ToString().Replace("[_", "").Replace("_]", ""); 
         var replacement = manager.GetString(key, sCulture) ?? match.ToString(); 
         result = result.Replace(match.ToString(), replacement); 
         if (!replacement.Contains("[_")) 
         { 
          matches = regexp.Matches(result); 
         } 
         else 
         { 
          shortCircuit = true; 
          break; 
         } 

        } 
       } 
      } 
      return result; 
     } 
    } 

回答

1

我已經找到了解決辦法。我不得不改變GetCodeExpression使用CodeMethodInvokeExpression

public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) 
     { 
      var type = entry.DeclaringType; 
      if (entry.DeclaringType != null) 
      { 
       return new CodeCastExpression(typeof(string), new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(base.GetType()), "TranslateAndFill", 
        new CodePrimitiveExpression(entry.Expression.Trim()))); 
      } 
      return new CodePrimitiveExpression((string)parsedData); 

     }