2
\$\begingroup\$

I am constructing a form builder in ASP.NET and I am wanting help with the structure of my POCO classes I have the following so far. I just don't see why I need to add to a list and then process it further again would their be a neater way to return a list of .net controls just to add to Panel using LoadControl(controlname).

POCO Class

public class FormClass
    {

        public string name { get; set; }
        public string displayName { get; set; }
        // This may actually work with Type, but I'm not so sure
        public string type { get; set; }
        public int length { get; set; }
        public bool key { get; set; }
        public bool required { get; set; }
        public string ControlType { get; set; }


    }

And then I'm using the following code to populate a list for further processing:

    PortalContext DBConext = new PortalContext();
    List<FormClass> formData = new List<FormClass>();
    List<FormStructure> frmstructList = new List<FormStructure>();
    public List<FormStructure> GetFormDataFromService()
    {   // XNamespace xNamespace = "http://CompanyName.AppName.Service.Contracts";



        Guid newGuid = Guid.NewGuid();
        XElement xdoc = XElement.Load(@"c:\form.xml");
        XNamespace ns = xdoc.GetDefaultNamespace();
        var classDetails = from classDetail in xdoc.Descendants(ns + "ClassDetails")
                           select new FormClass
                           {
                               name = (string)classDetail.Element(ns + "name"),
                               type = (string)classDetail.Element(ns + "type"),                                  
                               displayName = (string)classDetail.Element(ns + "displayName"),
                               length = (int)classDetail.Element(ns + "length"),
                               key = (bool)classDetail.Element(ns + "key"),
                               required = (bool)classDetail.Element(ns + "required"),
                           };

        foreach (FormClass classDetail in classDetails)
        {
              FormStructure frmstruct = new FormStructure();
              frmstruct.FormStructureId = newGuid;
              frmstruct.name = classDetail.name;
              frmstruct.displayname = classDetail.displayName;
              frmstruct.FormKey = classDetail.key;
              frmstruct.Required = classDetail.required;
              frmstruct.ClassName = "Incident";

              if (classDetail.type == "System.String")
                  frmstruct.ControlType = "TextBox";

              if (classDetail.type == "System.Enum") //to be dropdown
                  frmstruct.ControlType = "DropDown";

              if (classDetail.type == "System.DateTime")//date picker            
                  frmstruct.ControlType = "DateTimePicker";

              if (classDetail.type == "System.Boolean")
                  frmstruct.ControlType = "RadioButton";






              frmstructList.Add(frmstruct);


        }
        return frmstructList;


    }

XML Data

  <name>DisplayName</name>

  <displayName>Display Name</displayName>

  <parent>Object</parent>

  <type>System.String</type>

  <length>4000</length>

  <key>false</key>

  <required>false</required>

</ArrayOfClassDetails>
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
  1. Your naming conventions are a bit off. Property names (i.e. in FormClass) are commonly PascalCase.

  2. If you are not married to the XML file structure (i.e. it's under your control) then you can simplify the de/serialization quite a lot by using the XmlSerializer. For example:

    public class ClassDetails
    {
        public List<FormClass> Models { get; set; }
    }
    
    public static class XmlUtils
    {
    
        public static void Save<T>(T obj, string filename, string namespace)
        {
             using (var writer = new StreamWriter(filename))
             {
                 var serializer = new XmlSerializer(typeof(T), namespace);
                 serializer.Serialize(writer, obj);
             }
        }
    
        public static T Load<T>(string filename, string namespace)
        {
             using (var writer = new StreamWriter(filename))
             {
                 var serializer = new XmlSerializer(typeof(T), namespace);
                 return (T)serializer.Deserialize(writer);
             }
        }
    }
    

    then you can load/save the file with:

    var details = XmlUtils.Load<ClassDetails>(@"c:\form.xml", "http://CompanyName.AppName.Service.Contracts");
    
    ...
    
    XmlUtils.Save(details, @"c:\form.xml", "http://CompanyName.AppName.Service.Contracts");
    
  3. Rather than having a big if-else cascade I'd use a dictionary to map the types:

    Dictionary<string, string> ModelToFormTypeMap = 
        new Dictionary<string, string> {
              { "System.String", "TextBox" },
              { "System.Enum", "DropDown" },
              ...
            };
    

    then with an addition of a little bit of Linq you get

    XmlUtils.Load<ClassDetails>((@"c:\form.xml", "http://CompanyName.AppName.Service.Contracts")
            .Models
            .Select(m => new FormStructure 
                         {
                              FormStructureId = newGuid,
                              name = m.name,
                              displayname = m.displayName,
                              FormKey = m.key,
                              Required = m.required,
                              ClassName = "Incident",
                              ControlType = ModelToFormTypeMap[m.type]
                         })
             .ToList();
    
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.