Рекомендации по использованию файлов ресурсов ASP.NET MVC
-
18-09-2019 - |
Вопрос
Как лучше всего использовать следующие файлы ресурсов.
- Свойства → Ресурсы (Фил использовал этот ресурс для локализации в DataAnnotation)
- Папка App_GlobalResources
- Папка App_LocalResources
Я также хотел бы знать, в чем разница между (1) и (2) в приложении asp.net mvc.
Решение
Вам следует избегать App_GlobalResources
и App_LocalResources
.Как упомянул Крейг, существуют проблемы с App_GlobalResources
/App_LocalResources
потому что вы не можете получить к ним доступ за пределами среды выполнения ASP.NET.Хорошим примером того, насколько это проблематично, является модульное тестирование вашего приложения.
К.Скотт Аллен недавно написал об этом в блоге.Он хорошо объясняет проблему App_GlobalResources
в ASP.NET MVC здесь.
Другие советы
Если вы выберете рекомендуемое решение (1) (т.е.раковина.Блог Скотта Аллена):
Для тех из вас, кто пытается использовать явные выражения локализации (так называемые декларативные выражения привязки ресурсов), например. <%$ Resources, MyResource:SomeString %>
public class AppResourceProvider : IResourceProvider
{
private readonly string _ResourceClassName;
ResourceManager _ResourceManager = null;
public AppResourceProvider(string className)
{
_ResourceClassName = className;
}
public object GetObject(string resourceKey, System.Globalization.CultureInfo culture)
{
EnsureResourceManager();
if (culture == null)
{
culture = CultureInfo.CurrentUICulture;
}
return _ResourceManager.GetObject(resourceKey, culture);
}
public System.Resources.IResourceReader ResourceReader
{
get
{
// Not needed for global resources
throw new NotSupportedException();
}
}
private void EnsureResourceManager()
{
var assembly = typeof(Resources.ResourceInAppToGetAssembly).Assembly;
String resourceFullName = String.Format("{0}.Resources.{1}", assembly.GetName().Name, _ResourceClassName);
_ResourceManager = new global::System.Resources.ResourceManager(resourceFullName, assembly);
_ResourceManager.IgnoreCase = true;
}
}
public class AppResourceProviderFactory : ResourceProviderFactory
{
// Thank you, .NET, for providing no way to override global resource providing w/o also overriding local resource providing
private static Type ResXProviderType = typeof(ResourceProviderFactory).Assembly.GetType("System.Web.Compilation.ResXResourceProviderFactory");
ResourceProviderFactory _DefaultFactory;
public AppResourceProviderFactory()
{
_DefaultFactory = (ResourceProviderFactory)Activator.CreateInstance(ResXProviderType);
}
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
return new AppResourceProvider(classKey);
}
public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
{
return _DefaultFactory.CreateLocalResourceProvider(virtualPath);
}
}
Затем добавьте это в свой web.config:
<globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" culture="en-US" uiCulture="en"
resourceProviderFactoryType="Vendalism.ResourceProvider.AppResourceProviderFactory" />
Свойства → Ресурсы можно увидеть за пределами ваших представлений, а строгие типы генерируются при компиляции приложения.
App_* компилируется ASP.NET при компиляции ваших представлений.Они доступны только в представлении.Видеть эта страница для глобального vs.местный.