24

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

我发现以下属性:

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

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

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

4

1 回答 1

22

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

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

  1. 使用默认 Internet 模板创建新的 ASP.NET MVC 3 应用程序
  2. 添加~/Messages.resx包含RegisterModel_ConfirmPasswordError资源字符串的文件
  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
  • ...

更新:

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

在此处输入图像描述

于 2013-02-07T21:55:50.813 回答