【问题标题】:Localization and DataAnnotations. GlobalResourceProxyGenerator and PublicResxFileCodeGenerator本地化和数据注释。 GlobalResourceProxyGenerator 和 PublicResxFileCodeGenerator
【发布时间】:2013-02-03 17:12:13
【问题描述】:

为什么 DataAnnotation 属性难以访问 PublicResxFileCodeGenerator 创建的资源?

我发现如下属性:

[Compare("NewPassword", ErrorMessageResourceName = "RegisterModel_ConfirmPasswordError", ErrorMessageResourceType = typeof(Resources.Global))]

如果资源是使用 PublicResxFileCodeGenerator 创建的,将无法找到该资源。但是,使用 GlobalResourceProxyGenerator 创建的相同资源将正常工作。两个资源文件都设置为 Content 并位于 App_GlobalResources 中。我也尝试将默认语言放在 App_LocalResources 中,但似乎没有什么区别。 我的测试是我的辅助语言(GlobalResourceProxyGenerator)有效,但我的主要语言(PublicResxFileCodeGenerator)抛出异常(它无法找到资源文件)。如果我将两者都切换到 GlobalResourceProxyGenerator 那么一切都很好(但显然没有公共访问权限)。

有人知道这是为什么吗?我想将来将资源移到另一个程序集中。

【问题讨论】:

    标签: c# asp.net-mvc localization


    【解决方案1】:

    这是因为您将资源文件放在了App_GlobalResources 文件夹中,该文件夹是 ASP.NET 中的一个特殊文件夹。如果您将资源文件放在其他地方,这应该可以工作。这也可以是与您的 ASP.NET MVC 应用程序完全不同的项目。

    以下是您可以完成这项工作的步骤:

    1. 使用默认 Internet 模板创建新的 ASP.NET MVC 3 应用程序
    2. 添加一个包含RegisterModel_ConfirmPasswordError资源字符串的~/Messages.resx文件
    3. 将此资源文件的自定义工具设置为PublicResXFileCodeGenerator

    4. 添加模型:

      public class MyViewModel
      {
          [Compare("NewPassword", 
                   ErrorMessageResourceName = "RegisterModel_ConfirmPasswordError",
                   ErrorMessageResourceType = typeof(MvcApplication1.Messages))]
          public string Password { get; set; }
      
          public string NewPassword { get; set; }
      }
      
    5. 控制器:

      public class HomeController : Controller
      {
          public ActionResult Index()
          {
              return View(new MyViewModel());
          }
      
          [HttpPost]
          public ActionResult Index(MyViewModel model)
          {
              return View(model);
          }
      }
      
    6. 查看:

      @model MyViewModel
      
      @using (Html.BeginForm())
      {
          <div>
              @Html.LabelFor(x => x.Password)
              @Html.EditorFor(x => x.Password)
              @Html.ValidationMessageFor(x => x.Password)
          </div>
      
          <div>
              @Html.LabelFor(x => x.NewPassword)
              @Html.EditorFor(x => x.NewPassword)
              @Html.ValidationMessageFor(x => x.NewPassword)
          </div>
      
          <button type="submit">OK</button>
      }
      

    然后您可以通过提供相应的翻译来开始本地化:

    • Messages.fr-FR.resx
    • Messages.de-DE.resx
    • Messages.it-IT.resx
    • Messages.es-ES.resx
    • ...

    更新:

    我在 cmets 部分被问到 App_GlobalResources 文件夹有什么特别之处以及为什么它不能使用它。好吧,实际上你可以让它工作。您需要做的就是将Build Action 设置为Embedded Resource。默认情况下,当您将文件添加到 App_GlobalResources 文件夹时,Visual Studio 将其设置为 Content,这意味着该资源不会被合并到运行时程序集中,并且 ASP.NET MVC 找不到它:

    【讨论】:

    • 感谢您的回答。我本可以发誓我尝试过这个,但它可能与其他一些问题混淆了(尝试“修复” DislayAttribute 是我遇到的另一个问题)。最重要的是,我对原因更感兴趣。为什么在 Global_Resources 中找不到该资源文件? VS 正在执行什么过程导致文件无法放置在正确的位置,为什么?你知道吗?
    • @Quibblesome,我已更新我的答案以解决您的问题以及如何使其与App_GlobalResources 文件夹一起使用。
    猜你喜欢
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多