Advice with Dynamic Forms in ASP.NET MVC

前端 未结 4 1754
隐瞒了意图╮
隐瞒了意图╮ 2021-02-06 03:34

I am working on rendering a dynamic form in an ASP.NET MVC view that will meet these requirements:

  • Fields can be validated
  • State is preserved when the for
4条回答
  •  余生分开走
    2021-02-06 03:54

    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;
        }
    

提交回复
热议问题