C# 接口开发小工具 笔记

做了2年的接口开发,主要给移动端提供接口,整理了一套小工具,在这里记录一下。

1.非空字段检测

 接口某些字段不能为空,最开始进行空值检测是在方法里面,一个参数一个参数手动的检测是否为空,某些方法非空字段十几个的时候,代码臃肿,看着恶心,写着也烦,于是就利用特性和反射实现了自动空值检测。

 //特性声明

[AttributeUsage(AttributeTargets.Property)]
    public class NotNull : Attribute
    {
    }

 //使用方式

public class GetOrderListReq
    {
        [NotNull]
        public string uid { get; set; }
    }

//检测方法,CustomExp是我自定义的错误类

 public void NotNullCheck(object t)
        {
            var ps = t.GetType().GetProperties();
            foreach (var item in ps)
            {
                //var c = item.GetCustomAttributes(typeof(NotNull), false).FirstOrDefault(m => m.GetType().Name == "NotNull");
                var c = (NotNull)Attribute.GetCustomAttribute(item, typeof(NotNull));
                if (c != null)
                {
                    if (item.GetValue(t, null) == null)
                        throw new CustomExp(4, item.Name + "不能为空!");
                }
            }
        }

检测流程。提前约定所有方法的形参均为一个类对象,在调用方法前先把实参检测一遍,成功了再调用方法。

2.默认值设置

 其实和非空检测大同小异,C#有提供一个DefaultValue特性,不过我习惯用自己的东西~

 

[AttributeUsage(AttributeTargets.Property)]
    public class MyDefaultValue : Attribute
    {
        //默认值
        public object Value { get; set; }
    }
 public class GetOrderListReq
    {
        [NotNull]
        public string uid { get; set; }
        [NotNull]
        public DateTime ltime { get; set; }
        [MyDefaultValue(Value = 1)]
        public int index { get; set; }
        [MyDefaultValue(Value = 10)]
        public int size { get; set; }
    }
 public void SetDefaultValue(object t)
        {
            var a = t.GetType().GetProperties();
            foreach (var item in a)
            {
                var deault = (MyDefaultValue)Attribute.GetCustomAttribute(item, typeof(MyDefaultValue));
                if (deault != null)
                {
                    item.SetValue(t, deault.Value, null);
                }
            }
        }

3.方法路由

 接口方法可能成百上千,如果用if或switch判断调用哪个方法能写到人奔溃~所以我用反射写了个方法路由,速度肯定没if快,但是就算接口有1000个方法,遍历一遍也用不了多久,所以这点性能损失可以接受。类名+方法名确定唯一一个方法,arguments是方法实参对象的json字符串。返回值是一个类对象,视前端需要可以进行json序列化或xml序列化

public object GetEntry(string className, string MethodName, string arguments)
        {
            var ts = Assembly.GetExecutingAssembly().GetTypes();
            object response = "";

            bool notSuch = true;

            Type resType;
            Type reqType;

            foreach (var t in ts)
            {
                if (t.Name == className)
                {
                    //实例类对象
                    var objClass = Assembly.GetExecutingAssembly().CreateInstance(t.FullName);
                    //获取类里面的方法
                    MethodInfo m = t.GetMethod(MethodName);
                    if (m != null)
                    {
                        notSuch = false;
                        //获取请求及响应对象的类型
                        resType = m.ReturnType;
                        if (m.GetParameters().Count() > 0)
                        {
                            reqType = m.GetParameters()[0].ParameterType;
                            if (arguments == null)
                                throw new CustomExp(2, "该接口的参数不能为空!");
                        }
                        else
                        {
                            reqType = null;
                        }

                        //反序列化字符串参数,生成参数对象并放入参数队列
                        object[] arg = new object[1];
                        if (!string.IsNullOrEmpty(arguments) && reqType != null)
                        {
                            arg[0] = Json.JsonDes(arguments, reqType);
                        }
                        else
                            arg = null;

                        //执行方法并获取返回的对象并序列化为字符串
                        try
                        {
                            //参数不为空则进行非空检测及默认值设置
                            if (arg != null)
                            {
                                NotNullCheck(arg[0]);
                                SetDefaultValue(arg[0]);
                            }
                            response = m.Invoke(objClass, arg);
                            break;
                        }
                        catch (Exception E)
                        {
                            //获取内部传递的异常,因为invoke会自动增加一层调用方法错误异常
                            throw E.GetBaseException();
                        }
                    }
                }
            }
            if (notSuch)
                throw new CustomExp(3, "接口不存在!");
            return response;
        }

 

posted on 2014-11-07 11:37  Sun_Yang_  阅读(1299)  评论(0编辑  收藏  举报

导航