I am working on rendering a dynamic form in an ASP.NET MVC view that will meet these requirements:
Although not an expert I had to create a solution where my main object had a list of values. Lets call it Object A has a list of ApplicationValues that are mapped in the database. The ApplicationValues have a Key (the form field e.g. PhoneNumber) and the Value.
As the ApplicationValues were an EntitySet I had to create get and set methods to correctly handle setting a specific ApplicationValue. I also had a list of ApplicationRules in my database that defined what these application values could take.
Here is a snippet of code that may help you develop a solution for your needs.
public partial ApplicationValue
{
public string Key;
public string Value;
}
public partial ApplicationRule
{
public string ValidationFormat;
public string ValidationError;
public bool Required;
}
public partial class A
{
public void SetValue(string key, string value)
{
//ApplicationValues is the list of values associated to object A
ApplicationValue v = ApplicationValues.SingleOrDefault
(k => k.Key == key);
//if we already have this value
if (v != null)
{ //...then we can simply set and return
v.Value = value;
return;
}
//else we need to create a new ApplicationValue
v = new ApplicationValue
{
AffinityID = this.ID,
Key = key,
Value = value
};
ApplicationValues.Add(v);
}
public string GetValue(ApplicationField key)
{
return GetValue(key, String.Empty);
}
public string GetValue(ApplicationField key, string defaultValue)
{
if (ApplicationValues == null)
return defaultValue;
ApplicationValue value = ApplicationValues.SingleOrDefault
(f => f.Key == key.ToString());
return (value != null) ? value.Value : defaultValue;
}
And then to do the form validation I loop through ApplicationRules (which defines if a field is required, contains a regex etc) and match it to the FormCollection.
public ActionResult Details(FormCollection form)
{
IList applicationRules = //get my rules from the DB
if (!(ValidateApplication(applicationRules, form, a)))
{
ModelState.AddModelError("message", "Please review the errors below.");
return View(a);
}
...
}
private bool ValidateApplication(IList applicationRules,
FormCollection form, A a)
{
//loop through the application rules
foreach (ApplicationRule ar in applicationRules)
{
//try and retrieve the specific form field value using the key
string value = form[ar.Key];
if (value == null)
continue;
//set the model value just in case there is an error
//so we can show error messages on our form
ModelState.SetModelValue(ar.Key, ValueProvider[ar.Key]);
//if this rule is required
if (ar.Required)
{ //...then check if the field has a value
if (String.IsNullOrEmpty(value))
{
ModelState.AddModelError(ar.Key, "Field is required");
continue;
}
}
//if this rule has a validation format
if (!String.IsNullOrEmpty(ar.ValidationFormat))
{ //...then check the value is of the correct format
Regex re = new Regex(ar.ValidationFormat);
if (!re.IsMatch(value))
{
ModelState.AddModelError(ar.Key, ar.ValidationError);
continue;
}
}
a.SetValue(ar.Key, value);
}
return ModelState.IsValid;
}