First you have to create a database table, TextBoxes
to hold the settings (which will also be modified from the administration panel), with the following columns:
CREATE TABLE TextBoxes
(
Id int NOT NULL PRIMARY KEY,
Ordinal int NOT NULL,
TextBoxName nvarchar(255) NOT NULL
);
Add a few records to it by using TextBoxName
values like name
, address
, state
etc - this will later be used to map the UI control - and the desired order in the Ordinal
column. Add the table to your model.
Create the following class (I'll assume that the entity containing the properties in the question is named Contact
):
public class MyDataAnnotationsModelMetadataProvider :
System.Web.Mvc.DataAnnotationsModelMetadataProvider
{
protected override System.Web.Mvc.ModelMetadata
CreateMetadata(IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
if (containerType == typeof(Contact))
{
// get the repository instance
var db = new MyModelEntities();
// find the current textbox by it's property name
var textBox = db.TextBoxes
.FirstOrDefault(t => t.TextBoxName == propertyName);
if (!string.IsNullOrWhiteSpace(propertyName) && textBox != null)
attributes = attributes.Union(new List<Attribute>() {
new DisplayAttribute() { Order = textBox.Ordinal }
});
}
return base.CreateMetadata(attributes,
containerType,
modelAccessor,
modelType,
propertyName);
}
}
In the Global.asax.cs file, modify the Application_Start
method:
protected void Application_Start()
{
// set the current metadata provider to our custom class
ModelMetadataProviders.Current = new MyDataAnnotationsModelMetadataProvider();
// other method content
AreaRegistration.RegisterAllAreas();
// etc
}
Note:
The example above will allow you to dynamically change the order of the text boxes for one model, but if you add another property in the TextBoxes
model to hold the order for the properties for multiple models, you could extend the logic to your other models through some extra filtering.