Подтвердить что ты не робот

Локализация и DataAnnotations. GlobalResourceProxyGenerator и PublicResxFileCodeGenerator

Почему атрибуты DataAnnotation имеют трудности с доступом к ресурсам, созданным PublicResxFileCodeGenerator?

Я нахожу, что следующий атрибут:

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

Не удалось найти ресурс, если он был создан с помощью PublicResxFileCodeGenerator. Однако идентичный ресурс, созданный с помощью GlobalResourceProxyGenerator, будет работать правильно. Оба файла ресурсов настроены на Content и живут в App_GlobalResources. Я попытался поставить язык по умолчанию в App_LocalResources, но, похоже, не имеет значения. Мой тест заключается в том, что мой вторичный язык (GlobalResourceProxyGenerator) работает, но мой основной язык (PublicResxFileCodeGenerator) генерирует исключение (он не может найти файл ресурсов). Если я переключу оба на GlobalResourceProxyGenerator, тогда все будет хорошо (но, очевидно, нет открытого доступа).

Кто-нибудь знает, почему это? Я хотел бы переместить ресурсы в другую сборку в будущем.

4b9b3361

Ответ 1

Это потому, что вы поместили свой файл ресурсов в папку App_GlobalResources, которая является специальной папкой в ​​ASP.NET. Это должно работать, если вы поместите файл ресурсов в другое место. Это также может быть совершенно отдельный проект из вашего приложения ASP.NET MVC.

Вот шаги, которые вы могли бы сделать этой работой:

  • Создайте новое приложение ASP.NET MVC 3 с использованием стандартного интернет-шаблона
  • Добавьте файл ~/Messages.resx, содержащий строку ресурса RegisterModel_ConfirmPasswordError
  • Задайте настраиваемый инструмент для PublicResXFileCodeGenerator для этого файла ресурсов:

    enter image description here

  • Добавить модель:

    public class MyViewModel
    {
        [Compare("NewPassword", 
                 ErrorMessageResourceName = "RegisterModel_ConfirmPasswordError",
                 ErrorMessageResourceType = typeof(MvcApplication1.Messages))]
        public string Password { get; set; }
    
        public string NewPassword { get; set; }
    }
    
  • контроллер:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new MyViewModel());
        }
    
        [HttpPost]
        public ActionResult Index(MyViewModel model)
        {
            return View(model);
        }
    }
    
  • Вид:

    @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
  • ...

UPDATE:

В разделе комментариев меня спросили, что так особенного в папке App_GlobalResources и почему он не работает с ним. Ну, на самом деле вы могли бы заставить его работать. Все, что вам нужно сделать, - установить Build Action на Embedded Resource. По умолчанию, когда вы добавляете файл в папку App_GlobalResources, Visual Studio установила его в Content, что означает, что этот ресурс не будет включен в сборку времени выполнения, а ASP.NET MVC не сможет найти его:

enter image description here