做了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; }
时间: 2024-10-19 10:09:40