WebApi interface parameter assignment

Currently, the interface uses [frombody] dictionary < string, string > req to receive.

Sometimes, it is necessary to extract multiple fields from the req dictionary and assign them to the model. A few are good, and dozens of assignments are bad. So we designed to use generics and reflection to help the assignment.

The design is not very general, as the number of types increases, this needs to continue to iterate.

public static A MapperThree<A>(Dictionary<string, string> req)
        {
            A a = Activator.CreateInstance<A>();
            try
            {               
                Type Typea = typeof(A);
                foreach (PropertyInfo propertyInfo in Typea.GetProperties())
                {
                    if (req.ContainsKey(propertyInfo.Name))
                    {
                        // Type t = ap.GetType();
                        string proName = propertyInfo.PropertyType.Name;
                        if (proName == "String")
                        {
                            propertyInfo.SetValue(a, req[propertyInfo.Name]);
                        }
                        else if (proName == "Int32")
                        {
                            propertyInfo.SetValue(a, Convert.ToInt32(req[propertyInfo.Name]));
                        }
                        else if (proName == "DateTime")
                        {
                            propertyInfo.SetValue(a, Convert.ToDateTime(req[propertyInfo.Name]));
                        }
                        else if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                        {
                            
                                Type[] typeArray = propertyInfo.PropertyType.GetGenericArguments();
                                Type baseType = typeArray[0];
                                if (baseType.Name== "Int32")
                                {
                                    propertyInfo.SetValue(a, Convert.ToInt32(req[propertyInfo.Name]));
                                }
                                else if (baseType.Name == "DateTime")
                                {
                                    propertyInfo.SetValue(a, Convert.ToDateTime(req[propertyInfo.Name]));
                                }
                          
                        }
                        else
                        {
                            //wrong int type and string ,datetime Type does not handle
                        }
                    }                  
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return a;
        }

There are two points of attention when writing this method

1: Get attribute type, official website https://docs.microsoft.com/en-us/dotnet/api/system.reflection.propertyinfo.propertytype?redirectedfrom=MSDN&view=netframework-4.7.2#System_Reflection_PropertyInfo_PropertyType 

2: Nullable type. The names are the same nullable`

That is, nullable < system. Datetime > and nullable < system. Int > have the same property type name

         

Solution: get the real type from the nullable generic parameters. The following code is designed according to the actual needs, and is not universal.

 

Of course, there are many ways to automatically assign values, such as binding parameters to objects, serializing and deserializing parameters to Json strings. Each has its own advantages and disadvantages. Weigh them according to the situation.

Tags: ASP.NET Attribute JSON

Posted on Sat, 04 Jan 2020 06:34:10 -0500 by GBahle