zoukankan      html  css  js  c++  java
  • 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;
            }
  • 相关阅读:
    Freemarker
    加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
    Jenkins入门
    kafka实战
    多线程文件下载
    Excel操作报表
    @Pointcut 使用@annotation 带参数
    博客园设置
    Windows下 tensorboard显示No graph definition files were found的问题解决
    通过GitHub Desktop 上传代码到github 远程仓库
  • 原文地址:https://www.cnblogs.com/sun-yang-/p/4080888.html
Copyright © 2011-2022 走看看