Наилучшая практика для ASP.NET файлы ресурсов MVC
Как лучше всего использовать следующие файлы ресурсов.
- → Свойства Ресурсов (Фил использовал этот ресурс для локализации в DataAnnotation)
- папку App_GlobalResources
- папке app_localresources
Я также хотел бы знать, в чем разница между (1) и (2) в asp.net приложение mvc.
3 ответов
вы должны избегать 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);
}
}
затем добавьте это в свою сеть.config:
<globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" culture="en-US" uiCulture="en"
resourceProviderFactoryType="Vendalism.ResourceProvider.AppResourceProviderFactory" />
свойства → ресурсы можно увидеть вне ваших представлений и сильные типы генерируются при компиляции приложения.
App_ * компилируется ASP.NET, когда ваши представления компилируются. Они доступны только в представлении. См.на этой странице глобальные и локальные.