由于工作需求,不得已要做一些业务接口,使用C#语言和Visual Studio2010开发完成。一开始真的完全不懂如何下手,慢慢的从网上查找一些这方面的资料,一步步地到现在可以自己独立完成接口的开发,其中也是经历了挺多挫折的。现在希望能够分享一下这方面的东西,也是为以后做个笔记吧。
Step1.创建WebService项目 1. 首先我们打开Visual Studio2010开发工具,点击导航栏—文件—新建项目,选择Visual C#–Web,选择ASP.NET空Web应用程序,项目名称可以随意定,点击确定。
2. 打开解决方案管理器,找到我们刚才创建的那个项目,右键—添加新建项,选择Web服务,名称也是由自己定,确定后就完成了项目的创建。
代码解析 我们双击打开后缀名为.asmx的文件,看到如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Services;namespace WebApplication2 { [WebService(Namespace = "http://tempuri.org/" ) ] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1) ] [System.ComponentModel.ToolboxItem(false) ] public class WebService1 : System.Web.Services.WebService { [WebMethod ] public string HelloWorld () { return "Hello World" ; } } }
这是开发工具自动帮我们生成的初始代码的demo,我们主要关注的是HelloWord这个方法,如果一个方法上面带有[WebMethod],则说明此方法是对外公开,可供外部调用的,说白了,这就是我们的接口,如果我们想对该方面写注释要怎么做呢?只需要把[WebMethod]改为[WebMethod(Description=”这是外部调用的接口”)],这样里面的中文说明在我们启动项目的时候就可以看到了。
Step2.项目代码的结构 上面我们已经创建好了项目,下面根据业务开始设计代码的结构,一个好的结构可以让我们更好地维护项目。现在以最近做的一个项目为例子,只是我自己设计的,可以根据自己的实际情况设计结构,接口的传入数据、返回数据都为xml格式。
我先讲解我的接口业务,涉及到查询数据、新增记录等,例如我们常见的 挂号 ,我就以挂号接口作为一个例子讲解实际业务。外部调用接口,传入必需的挂号相关信息,如订单号、号别、时段、挂号人信息、支付金额等,而我们的接口需要将这些传入的数据作为依据,查找是否存在对应的号源,如果信息无误,则完成挂号的操作,并且返回相应的订单信息给接口调用者。
那么我们确定好接口的传入参数是xml格式的字符串,返回的数据也是xml格式的字符串,如果要对这些数据进行操作,最好的办法就是把xml格式的字符串转化为类,使用一个泛型类将其序列化类,确定好数据的处理,下面我们开始设计结构。
下面是我设计的代码结构:
TJYD.Helper ——–存放工具类,例如我们刚才提到的序列化类
application ——–创建的项目
appliaction.Business ——-数据处理类,主要完成入参和出参的数据处理
application.Business.DAL ——-Model层,负责跟数据库交互
application.Business.Request ——–请求入参处理类
application.Business.Response ———返回数据处理类
Step3.代码实例 我们以一个实例来解释代码逻辑处理的过程。
1.接口代码 1 2 3 4 5 6 7 8 [WebMethod(Description = "号源信息查询" ) ] public string getRegInfo (string xml ){ string response = "" ; Business.Clinic.clinicBusiness.getClinicSource(xml,ref response); return response; }
注释:ref是对实例的引用,类似指针的作用。
1.数据处理类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 #region [ 号源信息 ] public static void getClinicSource(string requestXml, ref string response) { XmlHelper<Request.Clinic.getClinicSourceRequest> requestHelper = new XmlHelper<Request.Clinic.getClinicSourceRequest>(); XmlHelper<Response.Clinic.getClinicSourceResponse> responseHelper = new XmlHelper<Response.Clinic.getClinicSourceResponse>(); Response.Clinic.getClinicSourceResponse br = new Response.Clinic.getClinicSourceResponse(); br.clinicSourceResult = new Response.Clinic.clinicSourceResult(); br.clinicSourceResult.clinicSourceCollection = new List<Response.Clinic.clinicSourceCollection>(); //每天号源 Dictionary<string, List<YY_SG_WebService.Business.Response.Clinic.clinicSourceItem>> scheduleDateDic = new Dictionary<string, List<Response.Clinic.clinicSourceItem>>(); var request = requestHelper.Deserialize(requestXml); if (request != null) { BLL.Clinic.clinicBLL bll = new BLL.Clinic.clinicBLL(); bool isError = false; string ErrorMessage = ""; string resultCode = ""; var ds = bll.getClinicSource(request.clinicSource.branchCode, request.clinicSource.beginDate, request.clinicSource.endDate, request.clinicSource.deptCode, request.clinicSource.doctorCode, ref isError, ref ErrorMessage,ref resultCode); bool isData = true; //判断是否返回数据 if (ds.Tables[0].Columns.Contains("resultMessage")) { isData = false; } if (ds.Tables.Count > 0 && isData) { for (int i = 0; i < ds.Tables[0].Rows.Count; i++) { var dr = ds.Tables[0].Rows[i]; var date = dr["scheduleDates"].ToString(); YY_SG_WebService.Business.Response.Clinic.clinicSourceItem item = null; if (scheduleDateDic.ContainsKey(date)) { //在字典里面查找号源 item = scheduleDateDic[date].FirstOrDefault(d => d.doctorNo == dr["doctorNo"].ToString()); if (item == null) { item = new Response.Clinic.clinicSourceItem(); item.category = dr["category"].ToString(); item.deptCode = dr["deptCode"].ToString(); item.deptName = dr["deptName"].ToString(); item.doctorCode = dr["doctorNo"].ToString(); item.doctorNo = dr["doctorNo"].ToString(); item.doctorName = dr["doctorName"].ToString(); item.doctorSex = dr["doctorSex"].ToString(); item.doctorTelephone = dr["doctorTelephone"].ToString(); item.doctorSkill = dr["doctorSkill"].ToString(); item.doctorIntroduction = dr["doctorIntroduction"].ToString(); item.doctorTitle = dr["doctorTitle"].ToString(); item.picture = dr["picture"].ToString(); item.leftTotalNum = dr["leftTotalNum"].ToString(); item.clinicSourceDetail = new List<Response.Clinic.clinicSourceDetail>(); scheduleDateDic[date].Add(item); } } else { item = new Response.Clinic.clinicSourceItem(); item.category = dr["category"].ToString(); item.deptCode = dr["deptCode"].ToString(); item.deptName = dr["deptName"].ToString(); item.doctorCode = dr["doctorNo"].ToString(); item.doctorNo = dr["doctorNo"].ToString(); item.doctorName = dr["doctorName"].ToString(); item.doctorSex = dr["doctorSex"].ToString(); item.doctorTelephone = dr["doctorTelephone"].ToString(); item.doctorSkill = dr["doctorSkill"].ToString(); item.doctorIntroduction = dr["doctorIntroduction"].ToString(); item.doctorTitle = dr["doctorTitle"].ToString(); item.picture = dr["picture"].ToString(); item.leftTotalNum = dr["leftTotalNum"].ToString(); item.clinicSourceDetail = new List<Response.Clinic.clinicSourceDetail>(); scheduleDateDic.Add(date, new List<Response.Clinic.clinicSourceItem> { item }); } var detail = item.clinicSourceDetail.FirstOrDefault(d => d.timeFlag == dr["timeFlags"].ToString()); //时间段不存在,添加时间段 if (detail == null) { detail = new Response.Clinic.clinicSourceDetail(); detail.timeFlag = dr["timeFlags"].ToString(); detail.hasDetailTime = "1"; detail.beginTime = dr["beginTime"].ToString(); detail.endTime = dr["endTime"].ToString(); detail.workStatus = "1"; detail.totalNum = dr["totalNum"].ToString(); detail.leftNum = dr["leftTotalNum"].ToString(); detail.regFee = dr["regFee"].ToString(); detail.treatFee = dr["treatFee"].ToString(); detail.workId = ""; item.clinicSourceDetail.Add(detail); } } foreach (var date in scheduleDateDic.Keys) { Response.Clinic.clinicSourceCollection item = new Response.Clinic.clinicSourceCollection(); item.scheduleDate = date; item.clinicSourceItem = scheduleDateDic[date]; br.clinicSourceResult.clinicSourceCollection.Add(item); } } else { br.resultCode = resultCode; br.resultMessage =ds.Tables[0].Rows[0]["resultMessage"].ToString(); } br.resultCode = resultCode; } else { br.resultCode = "-1"; br.resultMessage = "传入参数不正确或者为空"; } response = responseHelper.Serialize(br); }
上面最开始我们用到了泛型类,生成了两个实例类,这两个类是根据入参出参构造出来的。
入参类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; namespace YY_SG_WebService.Business.Request.Clinic { [XmlRoot(ElementName = "request")] [Serializable] public class getClinicSourceRequest : BaseRequest { [XmlElement("params")] public clinicSource clinicSource { get; set; } } public class clinicSource { public string branchCode { get; set; } public string beginDate { get; set; } public string endDate { get; set; } public string deptCode { get; set; } public string doctorCode { get; set; } } }
出参类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Serialization; namespace YY_SG_WebService.Business.Response.Clinic { [XmlRoot(ElementName = "response")] [Serializable] public class getClinicSourceResponse:BaseResponse { [XmlElement("result")] public clinicSourceResult clinicSourceResult { get; set; } } public class clinicSourceResult { [XmlElement("collection")] public List<clinicSourceCollection> clinicSourceCollection { get; set; } } public class clinicSourceCollection { public string scheduleDate { get; set; } [XmlElement("item")] public List<clinicSourceItem> clinicSourceItem { get; set; } } public class clinicSourceItem { public string category { get; set; } public string deptCode { get; set; } public string deptName { get; set; } public string doctorCode { get; set; } public string doctorNo { get; set; } public string doctorName { get; set; } public string doctorSex { get; set; } public string doctorTelephone { get; set; } public string doctorSkill { get; set; } public string doctorIntroduction { get; set; } public string doctorTitle { get; set; } public string picture { get; set; } public string leftTotalNum { get; set; } [XmlElement("detail")] public List<clinicSourceDetail> clinicSourceDetail { get; set; } } public class clinicSourceDetail { public string timeFlag { get; set; } public string hasDetailTime { get; set; } public string beginTime { get; set; } public string endTime { get; set; } public string workStatus { get; set; } public string totalNum { get; set; } public string leftNum { get; set; } public string regFee { get; set; } public string treatFee { get; set; } public string workId { get; set; } } }
上面是我实际的业务构造的类,比较复杂,看实际情况构造,这里涉及到了C#的xml相关知识,具体可百度了解。
我们看到上面的数据处理类,关注的重点是 **bll.getClinicSource()**方法,由这个方法调用我们跟数据库交互的方法,然后返回DataSet(该数据为接口返回的业务数据),后面是对返回的业务数据根据约定的格式进行处理封装,responseHelper.Serialize这个方法是将返回业务数据类反序列化为xml格式字符串。其中由于返回的数据格式较为复杂,有四个层级,使用了Dictionary进行存储分类,再赋值给实例类。
数据库交互类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public DataSet getClinicSource(string branchCode, string beginDate, string endDate, string deptCode, string doctorCode, ref bool isError, ref string ErrorMessage,ref string resultCode) { List<OracleParameter> paramList = new List<OracleParameter>(); paramList.Add(DBHelper.createParameter("branchCode", 30, ParameterDirection.Input, branchCode)); paramList.Add(DBHelper.createParameter("beginDate", 30, ParameterDirection.Input, beginDate)); paramList.Add(DBHelper.createParameter("endDate", 30, ParameterDirection.Input, endDate)); paramList.Add(DBHelper.createParameter("deptCode", 30, ParameterDirection.Input,deptCode)); paramList.Add(DBHelper.createParameter("doctorCode", 30, ParameterDirection.Input, doctorCode)); paramList.Add(DBHelper.createParameter("curout", ParameterDirection.Output, OracleType.Cursor)); paramList.AddRange(DBHelper.CreateBaseParameter()); OracleParameter[] pm = paramList.ToArray(); DataSet ds = new DataSet(); try { ds = DBHelper.runProc_Ret_DataSet("proc_clinic_Info", ref pm); foreach (var op in pm) { if (op.ParameterName == "resultMessage") { ErrorMessage = op.Value.ToString(); } if (op.ParameterName == "resultCode") { resultCode = op.Value.ToString(); } } isError = false; } catch (Exception e) { isError = true; ErrorMessage = e.Message; TJYD.Helper.Logger.Write("proc_clinic_Info," + e.Message); } return ds; }
DBHelper.runProc_Ret_DataSet 该方法是调用数据库的存储过程,第一个参数是存储过程名称,第二个是存储过程入参,返回DataSet。
思绪有点凌乱,先写到这吧,有些东西想说清楚,但是又没法整理好逻辑关系,头疼(—)