企业库验证应用程序阻止和国际化

时间:2010-08-04 10:55:11

标签: .net localization enterprise-library globalization validation-application-bl

方案

.NET / WPF桌面应用程序应本地化(或以MS术语全球化)使用与英语不同的语言。也就是说,UI需要完全采用(标签,图标......)。

应用程序的日志文件条目,审计跟踪条目和其他输出应保留为英语,以便英语服务/支持人员对其进行审核。他们不讲法语或中文。

应用程序依赖于RESX文件来完成本地化。

企业库验证块用于验证对象模型上的业务规则。

现在假设有一个服务在执行实际业务逻辑之前验证其给定的对象模型参数。在某些情况下,它会收到无​​效的对象模型参数,但会尽最大努力继续执行。但是,应在审计跟踪和日志文件中记录无效对象模型数据的提供。

使用验证块的服务示例。

public class Service : IService
{
    public void MyMethod(MyObjectModelObject obj)
    {
        Validator validator = ValidationFactory.CreateValidator(typeof(MyObjectModelObject));
        ValidationResults results = validator.Validate(this);

        // !!! The messages in the validation results are now already localized to CurrentCulture.

        // ... build a log message: msg
        if (results.Count > 0)
        {
            Logger.Log(msg);
        }
    }
}

如代码注释中所述,当您在EnterpriseLibrary验证程序上调用Validate()时,验证消息已经本地化为法语,并且您没有机会将它们写入例如英文日志文件。

在我们的应用程序的其他方面,我们使用一个消息类来封装资源ID和参数,直到我们确定我们要使用哪种文化来解析实际的字符串值。您可以将其称为延迟资源解析。

有关如何将相似机制引入企业库验证块的任何想法?到目前为止的想法:

  • 暂时切换CurrentCulture(我不喜欢它,它只能解决问题的一半)
  • 修补企业库验证区块(我也不喜欢)

感谢您的帮助和分享想法!

1 个答案:

答案 0 :(得分:4)

当我们要求延迟资源解析时,我们放弃使用MessageTemplateResourceName,而是将我们的资源ID作为MessageTemplate属性。然后我们使用该id来使用当前文化查找资源字符串值。

我们将id的命名约定标准化为:RULESET_RULESETQUALIFIER_OPERATION_OBJECT_PROPERTY_VALIDATIONTYPE。例如RULESET_BMW_INSERT_CAR_YEAR_RANGERULESET_BMW_UPDATE_CAR_COLOR_LENGTH等。

在VAB配置中,这看起来像:

<property name="Color">
   <validator lowerBound="0" lowerBoundType="Ignore" upperBound="50"
    upperBoundType="Inclusive" negated="false" messageTemplate="RULESET_BMW_INSERT_CAR_COLOR_LENGTH"
    messageTemplateResourceName="" messageTemplateResourceType=""
    tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    name="String Length Validator" />
                    </property>

主要缺点是您无法轻松使用消息模板令牌来使消息略微动态化。这可以完成,但是必须将令牌值存储在某处(例如,您的消息类),以便在评估消息字符串时可以替换它们。

您可能还需要考虑为邮件所针对的每个受众群体创建多个资源文件。也就是说,一个用户消息资源和一个技术消息资源。因此,您可以拥有用户消息的UserMessages.resources,UserMessages.fr-BE.resources。然后在另一个资源文件中复制具有不同消息的ID以进行日志记录(LogMessages.resources)。这样您就可以获得日志消息的其他技术信息。但这可能有点过头了。

然后我们使用ResourceManager

访问字符串值
ResourceManager userResourceManager = 
    new ResourceManager("UserMessages", Assembly.GetExecutingAssembly());

string userMessage = userResourceManager.GetString(resourceId);

ResourceManager logResourceManager = 
    new ResourceManager("LogMessages", Assembly.GetExecutingAssembly());

// Can also try to use InvariantCulture instead of "en"
string messageToLog = logResourceManager.GetString(resourceId,  new CultureInfo("en"));
//alternative to ensure you get the english user message value:
//    string messageToLog = userResourceManager.GetString(resourceId,  new CultureInfo("en"));


您可以将其抽象为辅助类或将其添加到您的消息类中。您可能还需要构建一些代码来提取ValidationResults并使用您需要的信息创建消息类。