构思的一个功能简单的接口框架

1 篇文章 0 订阅

水平有限,不足之处烦请指点。

最近做移动WMS项目,遇到了一些问题,解决了一些问题,绕过了一些问题,是时候整理一下了。本文讲的是项目中涉及到一个数据通信的问题。以前在上家公司用的是直接是引入WebService,感觉这个不太好,每次变化后都要重新引用。新系统听取了其他人的建议,决定用ASP.NET网站来做。

目标定下了,就要补充细节。

1.本项目是纯粹的数据交互接口,没有页面,不对外展示,决定全部使用一般处理程序来做。

2.接口的一定要简洁明了,其它的数据判断、异常、耗时记录、数据接收和返回都封装好。后续的人只需要把逻辑代码向里面填充即可。

3.考虑到大部分是字符串类的数据,决定使用json作为数据格式。并约定好请求返回数据格式。

4.开工吧。


上张图



首先,是用到的类。

    // 主类
	public class ApiModel<T1, T2>
    {
        public HttpContext Context { get; set; }
        public Stopwatch Watch { get; set; }
        public WMS_ApiLogInfo ApiLogInfo { get; set; }// 统计类
        public RequestModel<T1> RequestModel { get; set; }
        public ResponseModel<T2> ResponseModel { get; set; }
        public string Msg { get; set; }
    }
	
	// 请求数据
	public class RequestModel<T>
    {
        /// <summary>
        ///     用户名:工号
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        ///     密码
        /// </summary>
        public string PassWord { get; set; }

        /// <summary>
        ///     设备号
        /// </summary>
        public string DeviceNo { get; set; }

        /// <summary>
        ///     设备IP
        /// </summary>
        public string IP { get; set; }

        /// <summary>
        ///     请求时间
        /// </summary>
        public DateTime RequesTime
        {
            get { return DateTime.Now; }
        }

        /// <summary>
        ///     请求数据
        /// </summary>
        public T RequestData { get; set; }
    }
	
	// 返回数据
    public class ResponseModel<T>
    {
        public bool IsSucc { get; set; }

        public string ErrMsg { get; set; }

        public T ReturnModel { get; set; }
    }
	
    [Serializable]
    public class WMS_ApiLogInfo
    {
        public string Guid { get; set; }

        public string ApiName { get; set; }

        public string UserName { get; set; }

        public DateTime? StartTime { get; set; }

        public DateTime? EndTime { get; set; }

        public string IP { get; set; }

        public string MacAddress { get; set; }

        public string RequestData { get; set; }

        public string ResponseData { get; set; }

		// 耗时
        public string UseTime { get; set; }
    }

具体的写法,一般处理程序封装

    /// <summary>
    ///     $codebehindclassname$ 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public abstract class Base<T1, T2> : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            ApiModel<T1, T2> apiModel = new ApiModel<T1, T2>
            {
                Context = context,
                Watch = new Stopwatch(),
                ApiLogInfo = new WMS_ApiLogInfo()
                {
                    StartTime = DateTime.Now,
                    ApiName = context.Request.CurrentExecutionFilePath,
                    Guid = Guid.NewGuid().ToString(),
                },
                ResponseModel = new ResponseModel<T2>() {IsSucc = false}
            };
            try
            {
                if (!Check(apiModel)) return;

                Do(apiModel);
            }
            catch (Exception ex)
            {
                apiModel.ResponseModel.ErrMsg = ex.Message;
                ResponseMsg(apiModel);
            }
        }

        public bool IsReusable
        {
            get { return false; }
        }

		// 合法数据验证
        public virtual bool Check(ApiModel<T1, T2> apiModel)
        {
            apiModel.Watch.Start();
            apiModel.Context.Response.ContentType = "text/plain";
            if (apiModel.Context.Request.HttpMethod != "POST")
            {
                apiModel.Msg = "请使用POST方法请求!";
                ResponseMsg(apiModel);
                return false;
            }
            string requestStr = string.Empty;
            using (Stream resStream = HttpContext.Current.Request.InputStream)
            {
                using (StreamReader sr = new StreamReader(resStream, Encoding.Default))
                {
                    requestStr = sr.ReadToEnd();
                }
            }
            apiModel.ApiLogInfo.RequestData = requestStr;
            apiModel.RequestModel = JsonConvertHelper.Json2Entity<RequestModel<T1>>(requestStr);

            if (apiModel.RequestModel == null)
            {
                apiModel.Msg = "没有POST数据!";
                ResponseMsg(apiModel);
                return false;
            }            

            apiModel.ApiLogInfo.MacAddress = apiModel.RequestModel.DeviceNo;
            apiModel.ApiLogInfo.UserName = apiModel.RequestModel.UserName;
            apiModel.ApiLogInfo.IP = apiModel.RequestModel.IP;
			
            // 设备检查
            // 员工检查

            return true;
        }

	// 子类重载,然后构建逻辑
        public virtual void Do(ApiModel<T1, T2> apiModel)
        {
        }

        /// <summary>
        ///     创建接口日志
        /// </summary>
        /// <param name="apiModel"></param>
        private void CreateApiLog(ApiModel<T1, T2> apiModel)
        {
            if (apiModel.Watch == null || apiModel.ApiLogInfo == null) return;
            apiModel.ApiLogInfo.EndTime = DateTime.Now;
            apiModel.Watch.Stop();            
            apiModel.ApiLogInfo.UseTime = Method.GetUseTime(apiModel.Watch);
            // 创建接口调用日志
        }

        /// <summary>
        ///     输出结果
        /// </summary>
        /// <param name="apiModel"></param>
        public void ResponseMsg(ApiModel<T1, T2> apiModel)
        {
            string result = string.Empty;
            apiModel.ResponseModel.ErrMsg = apiModel.Msg;
            result = JsonConvertHelper.Obj2Json(apiModel.ResponseModel);
            apiModel.Context.Response.Write(result);
            apiModel.ApiLogInfo.ResponseData = result;
            CreateApiLog(apiModel);
        }

        // 邮件方法、短信方法等等,供子类使用
    }
子类的写法,两个示例
    public class GetJHDHList : Base<string, List<string>>
    {
        public override void Do(ApiModel<string, List<string>> apiModel)
        {
            // 逻辑代码
            List<JHDInfo> list = new List<JHDInfo>();

	// 没有数据
            if (list.Count == 0)
            {
                apiModel.Msg = "没有查到可拣单号列表!";
            }
            else
            {
				// 有数据
                apiModel.ResponseModel.ReturnModel =
                    list.Select(o => o.JHDH).ToList();

                apiModel.ResponseModel.IsSucc = true;
            }
            ResponseMsg(apiModel);
        }
    }
	
    public class LoginIn : Base<string, XT_YGInfo>
    {
        public override void Do(ApiModel<string, XT_YGInfo> apiModel)
        {
            // 逻辑代码,检查用户是否能登录
			
			// 失败,提示
			var flag=false;
            if (flag)
            {
                apiModel.Msg = "密码错误!";
                ResponseMsg(apiModel);
                return;
            }

            // 成功,返回PDA权限、仓库、用户名等等信息。

            apiModel.ResponseModel.IsSucc = true;
            apiModel.ResponseModel.ReturnModel = info;
            ResponseMsg(apiModel);
        }
    }
公共方法

    // 使用的json.net做类型转换
	public class JsonConvertHelper
    {
        public static string Obj2Json(object obj)
        {
            try
            {
                return JsonConvert.SerializeObject(obj);
            }
            catch (Exception ex)
            {
                throw new Exception("JsonConvertHelper.Obj2Json():" + ex.Message);
            }
        }

        public static T Json2Entity<T>(string jsonstr)
        {
            try
            {
                return JsonConvert.DeserializeObject<T>(jsonstr);
            }
            catch (Exception ex)
            {
                throw new Exception("JsonConvertHelper.Json2Entity():" + ex.Message);
            }
        }
    }
	
    public class Method
    {
        public static string GetUseTime(Stopwatch watch)
        {
            if (watch == null)
                return null;
            return watch.Elapsed.Days + ":" + watch.Elapsed.Hours + ":" + watch.Elapsed.Minutes + ":" +
                   watch.Elapsed.Seconds + ":" + watch.Elapsed.Milliseconds;
        }
    }

ok,完成了,上面只写了UI层的调用关系,可以和其他层接驳。不过,PDA端的代码及逻辑没有贴出来。

主要是涉及到太多的项目内调用。我具体的做法是建一个api的项目,里面写的都是调用具体的方法,处理http请求和返回数据的一段代码封装一下。

然后在UI层创建api请求数据,并处理返回数据。


做这个项目最大的收获就是大部分架构都是我构思设计的,可能有些微bug、可能功能较弱,但我收获的更多。对项目的理解更深,对代码的堆砌更有心得。


-----------

每天进步一点点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值