If you use Dynamic Data sooner or later you'll need localization.
Just to note I'm using Entity Framework.
First part shows how to localize model table names.
So here is my inspiration:Just to note I'm using Entity Framework.
First part shows how to localize model table names.
http://carstent.com/2009/12/23/aspnet-dynamic-data-4-ui-table-localization/
I've simple translated it to C#. Tested, it works, like charm.
Oh yes, I'm using Log4Net.
Table names
/// <summary>
/// Supports localization
/// </summary>
public class BackOfficeMetaTable : MetaTable
{
private readonly ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public BackOfficeMetaTable(MetaModel metaModel, TableProvider tableProvider) : base(metaModel,tableProvider)
{
}
public BackOfficeMetaTable(MetaModel metaModel, TableProvider tableProvider, string globalResourceClassNameParam):base(metaModel,tableProvider)
{
globalResourceClassName = globalResourceClassNameParam;
}
private readonly string globalResourceClassName;
protected override void Initialize()
{
base.Initialize();
}
public override string DisplayName
{
get
{
Log.Info("Try obtaining display name.");
var baseDisplayName = base.DisplayName;
if (string.IsNullOrWhiteSpace(globalResourceClassName)) return baseDisplayName;
string resourceKey = string.Concat("DDtable_", baseDisplayName);
try
{
return HttpContext.GetGlobalResourceObject(globalResourceClassName, resourceKey).ToString();
}
catch (System.Exception e)
{
Log.Error(string.Format("Can't find resource key->{0}", resourceKey),e );
}
return baseDisplayName;
}
}
}
/// <summary>
/// Support for DD localization
/// </summary>
public class BackOfficeMetaModel : MetaModel
{
public BackOfficeMetaModel() : base()
{
}
public BackOfficeMetaModel(string globalResourceClassNameParam)
{
globalResourcesClassName = globalResourceClassNameParam;
}
private readonly string globalResourcesClassName;
protected override MetaTable CreateTable(System.Web.DynamicData.ModelProviders.TableProvider provider)
{
if (string.IsNullOrWhiteSpace(globalResourcesClassName)) return base.CreateTable(provider);
else return new BackOfficeMetaTable(this, provider, globalResourcesClassName);
}
}
Fields
Second part shows how to localize Fields.
I've tried using System.ComponentModel.DataAnnotations.Display attribute.
This required making global resources files public :
http://holyhoehle.wordpress.com/2010/02/20/making-global-resources-public/
It looked all fine on local IIS but on production Release version I keep getting error that res.key can't be found. Don't use this unless you can figure out how to make it work.
Here it is code that uses Display and may give you trouble:
[ScaffoldTable(true)]
public class Customer_Metadata
{
[Display(ResourceType = typeof(GlobalLocalization), Name = "MenuCustomers", ShortName = "MenuCustomers")]
public object Name { get; set; }
}
GlobalLocalization is Global Resource class name.
[MetadataType(typeof(Customer_Metadata))]
public partial class Customer
{
}
I was lucky since my coworker wrote attribute for localization:
Here it is:
public class ResourceDisplayNameAttribute : DisplayNameAttributeYou can use it like this:
{
#region Static Fields
/// <summary>
/// The resourceManagers Field
/// </summary>
private static readonly SortedList<string, ResourceManager> ResourceManagers = new SortedList<string, ResourceManager>();
/// <summary>
/// The syncLock Field
/// </summary>
private static readonly object SyncLock = new object();
#endregion
#region Fields
/// <summary>
/// replaced field
/// </summary>
private bool replaced;
/// <summary>
/// The resourceType Field
/// </summary>
private readonly string resourceType = "Resources.Shared";
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="ResourceDisplayNameAttribute" /> class.
/// </summary>
/// <param name="resourceKey">The resource key used for display name.</param>
public ResourceDisplayNameAttribute(string resourceKey)
: base(resourceKey)
{
}
public ResourceDisplayNameAttribute(string resourceKey, string resourceType)
: base(resourceKey)
{
this.resourceType = resourceType;
}
#endregion
#region Public Properties
/// <summary>
/// Gets the display name for a property, event, or public void method that takes no arguments stored in this
/// attribute.
/// </summary>
/// <value></value>
/// <returns>The display name.</returns>
public override string DisplayName
{
get
{
if (!this.replaced)
{
this.replaced = true;
this.DisplayNameValue = this.GetString();
}
return base.DisplayName;
}
}
/// <summary>
/// Gets the string.
/// </summary>
/// <returns></returns>
private string GetString()
{
ResourceManager resourceManager = GetResourceManager(this.resourceType);
return resourceManager.GetString(base.DisplayName);
}
/// <summary>
/// Gets the resource manager.
/// </summary>
/// <param name="resourceType">Type of the resource.</param>
/// <returns></returns>
private static ResourceManager GetResourceManager(string resourceType)
{
lock (SyncLock)
{
if (ResourceManagers.ContainsKey(resourceType))
{
return ResourceManagers[resourceType];
}
ResourceManager resourceManager = new ResourceManager(resourceType, System.Reflection.Assembly.Load("App_GlobalResources"));
if (!ResourceManagers.ContainsKey(resourceType))
{
ResourceManagers.Add(resourceType, resourceManager);
}
return ResourceManagers[resourceType];
}
}
/// <summary>
/// When implemented in a derived class, gets a unique identifier for this <see cref="T:System.Attribute" />.
/// </summary>
/// <value></value>
/// <returns>An <see cref="T:System.Object" /> that is a unique identifier for the attribute.</returns>
public override object TypeId
{
get
{
return typeof(DisplayNameAttribute);
}
}
#endregion
}
[ScaffoldTable(true)]
public class Customer_Metadata
{
[ResourceDisplayName("CustomerName", "Resources.DBColumns")]
public string Name { get; set; }
Foreign key
By default each list has on top list of foreign key filters. You localize them same way as fields above just reference correct property from model like bellow or you could use above custom attribute.
[MetadataType(typeof(User_Metadata))]
public partial class User
{
}
[ScaffoldTable(true)]
public class User_Metadata
{
[Display(ResourceType=typeof(App_GlobalResources.GlobalLocalization),Name="MenuCustomers",ShortName="MenuCustomers")]
public virtual Customer Customer { get; set; }
}
No comments:
Post a Comment