赞
踩
前面完成了服务端数据库表的创建。这篇文章,我们来继续服务端Web API和逻辑的实现,并把程序部署到主机网站空间。
由于我们使用C#开发,可以使用Visual Studio开发环境进行程序开发和发布,版本从VS 2008到VS 2019均可。
新建一个ASP. NET Web应用程序项目。
对应数据表结构,创建卡片大类、卡片小类、卡片实体类。
public class B_Category
{
public B_Category()
{
Types = new List<B_Type>();
}
public int Id { get; set; }
public string Name { get; set; }
// 存放当前卡片大类下的卡片小类列表
public List<B_Type> Types { get; set; }
}
public class B_Type
{
public int Id { get; set; }
public string Name { get; set; }
public int Sequential { get; set; }
public int ImageMode { get; set; }
public string ImageVer { get; set; }
}
public class B_Card
{
public int Id { get; set; }
public string Name1 { get; set; }
public string Name2 { get; set; }
public string Name3 { get; set; }
public string ImageVer { get; set; }
}
public static class Dao { private static string connectionString = null; static Dao() { connectionString = ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["DBConnection"]].ConnectionString; } public static string GetConnectionString() { return connectionString; } public static DataTable Fill(string sqlText, IDictionary<string, object> param) { DataTable result = new DataTable("Result"); using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open(); SqlDataAdapter adapter = new SqlDataAdapter(sqlConnection.CreateCommand()); adapter.SelectCommand.CommandText = sqlText; SetParameter(adapter.SelectCommand, param); adapter.Fill(result); } return result; } public static DataTable FillByStoredProcedure(string sqlText, IDictionary<string, object> param, int timeout) { DataTable result = new DataTable("Result"); using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open(); SqlDataAdapter adapter = new SqlDataAdapter(sqlConnection.CreateCommand()); adapter.SelectCommand.CommandType = CommandType.StoredProcedure; adapter.SelectCommand.CommandTimeout = timeout; adapter.SelectCommand.CommandText = sqlText; SetParameter(adapter.SelectCommand, param); adapter.Fill(result); } return result; } public static DataRow Get(string sqlText, IDictionary<string, object> param) { DataTable data = Fill(sqlText, param); if (data.Rows.Count > 0) return data.Rows[0]; else return null; } public static int Execute(string sqlText, IDictionary<string, object> param) { int result; using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open(); SqlCommand sqlCommand = sqlConnection.CreateCommand(); sqlCommand.CommandText = sqlText; SetParameter(sqlCommand, param); result = sqlCommand.ExecuteNonQuery(); } return result; } public static int Execute(string sqlText, List<IDictionary<string, object>> paramList) { List<string> sqlTextList = new List<string>(); for (int i = 0; i < paramList.Count; i++) { sqlTextList.Add(sqlText); } return Execute(sqlTextList, paramList); } public static int Execute(List<string> sqlTextList, List<IDictionary<string, object>> paramList) { int result = 0; SqlTransaction sqlTransaction = null; using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open(); sqlTransaction = sqlConnection.BeginTransaction(); SqlCommand sqlCommand = sqlConnection.CreateCommand(); sqlCommand.Transaction = sqlTransaction; for (int i = 0; i < sqlTextList.Count; i++) { sqlCommand.CommandText = sqlTextList[i]; SetParameter(sqlCommand, paramList[i]); result += sqlCommand.ExecuteNonQuery(); } sqlTransaction.Commit(); } return result; } public static object ExecuteScalar(string sqlText, IDictionary<string, object> param) { object result; using (SqlConnection sqlConnection = new SqlConnection(connectionString)) { if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open(); SqlCommand sqlCommand = sqlConnection.CreateCommand(); sqlCommand.CommandText = sqlText; SetParameter(sqlCommand, param); result = sqlCommand.ExecuteScalar(); } return result; } public static bool Exists(string sqlText, IDictionary<string, object> param) { DataTable data = Fill(sqlText, param); return data.Rows.Count > 0; } public static int Count(string sqlText, IDictionary<string, object> param) { DataTable data = Fill(sqlText, param); return data.Rows.Count; } private static void SetParameter(SqlCommand sqlCommand, IDictionary<string, object> param) { sqlCommand.Parameters.Clear(); if (param == null || param.Count == 0) return; foreach (var item in param) { sqlCommand.Parameters.Add(new SqlParameter(item.Key, item.Value)); } } }
public class DataAccess { // 获取所有启用的卡片大类 public DataTable GetCategory() { string sqlText = @"select *from [Category] where [Status]=1 order by Rank,Id"; return Dao.Fill(sqlText, null); } // 根据卡片大类Id获取所有启用的卡片小类 public DataTable GetType(int CategoryId) { string sqlText = @"select *from [Type] where CategoryId=@CategoryId and [Status]=1 order by Rank,Id"; IDictionary<string, object> param = new Dictionary<string, object>() { { "CategoryId" , CategoryId }, }; return Dao.Fill(sqlText, param); } // 获取相应卡片小类Id的信息 public DataTable GetType2(int TypeId) { string sqlText = @"select *from [Type] where Id=@TypeId"; IDictionary<string, object> param = new Dictionary<string, object>() { { "TypeId" , TypeId }, }; return Dao.Fill(sqlText, param); } // 根据卡片小类Id获取所有启用的卡片大类,参数Sequential控制结果输出按照Rank定义顺序或是无序 public DataTable GetCard(int TypeId, int Sequential) { string order = "Rank,Id"; if (Sequential == 0) order = "NEWID()"; string sqlText = @"select *from [Card] where TypeId=@TypeId and [Status]=1 order by " + order; IDictionary<string, object> param = new Dictionary<string, object>() { { "TypeId" , TypeId }, }; return Dao.Fill(sqlText, param); } // 插入一条使用反馈信息 public int InsertFeedback(int Type, string Message, string Contacts) { string sqlText = @"insert into [Feedback](Type, Message, Contacts, Time) select @Type, @Message, @Contacts, getdate()"; IDictionary<string, object> param = new Dictionary<string, object>() { { "Type" , Type }, { "Message" , Message }, { "Contacts" , Contacts }, }; return Dao.Execute(sqlText, param); } }
从之前的功能分析,服务端我们需要至少提供以下3个API:
我们为每个API方法创建一个.ashx文件,这样客户端就可以直接post数据到这个文件URL,进行数据交互。
所以我们分别创建了3个文件:
public class GetType : IHttpHandler { public void ProcessRequest(HttpContext context) { // 获取所有卡片大类 List<B_Category> categories = new List<B_Category>(); DataTable data = new DataAccess().GetCategory(); // 遍历每个卡片大类,获取对应的卡片小类保存于大类里的Types列表 for (int i = 0; i < data.Rows.Count; i++) { Category category = new Category(); category.Id = Convert.ToInt32(data.Rows[i]["Id"]); category.Name = data.Rows[i]["Name"].ToString(); DataTable data2 = new DataAccess().GetType(category.Id); for (int j = 0; j < data2.Rows.Count; j++) { B_Type type = new B_Type(); type.Id = Convert.ToInt32(data2.Rows[j]["Id"]); type.Name = data2.Rows[j]["Name"].ToString(); type.Sequential = Convert.ToInt32(data2.Rows[j]["Sequential"]); type.ImageMode = Convert.ToInt32(data2.Rows[j]["ImageMode"]); type.ImageVer = data2.Rows[j]["ImageVer"].ToString(); category.Types.Add(type); } categories.Add(category); } string res = JsonConvert.SerializeObject(categories); context.Response.ContentType = "text/plain"; context.Response.Write(res); context.Response.End(); } public bool IsReusable { get { return false; } } }
public class GetCard : IHttpHandler { public void ProcessRequest(HttpContext context) { // 获取当前卡片小类的信息 string TypeId = context.Request["TypeId"]; int Sequential = 1; List<B_Card> cards = new List<B_Card>(); DataTable tdata = new DataAccess().GetType2(Convert.ToInt32(TypeId)); // 卡片小类的Sequential值,指示卡片是否按顺序输出 if (tdata.Rows.Count > 0) Sequential = Convert.ToInt32(tdata.Rows[0]["Sequential"]); // 获取当前卡片小类的所有卡片 DataTable data = new DataAccess().GetCard(Convert.ToInt32(TypeId), Sequential); for (int i = 0; i < data.Rows.Count; i++) { B_Card card = new B_Card(); card.Id = Convert.ToInt32(data.Rows[i]["Id"]); card.Name1 = data.Rows[i]["Name1"].ToString(); card.Name2 = data.Rows[i]["Name2"].ToString(); card.Name3 = data.Rows[i]["Name3"].ToString(); card.ImageVer = data.Rows[i]["ImageVer"].ToString(); cards.Add(card); } string res = JsonConvert.SerializeObject(cards); context.Response.ContentType = "text/plain"; context.Response.Write(res); context.Response.End(); } public bool IsReusable { get { return false; } } }
public class InsertFeedback : IHttpHandler { public void ProcessRequest(HttpContext context) { string Type = context.Request["Type"]; string Message = context.Request["Message"]; string Contacts = context.Request["Contacts"]; new DataAccess().InsertFeedback(Convert.ToInt32(Type), Message, Contacts); context.Response.ContentType = "text/plain"; context.Response.Write("ok"); context.Response.End(); } public bool IsReusable { get { return false; } } }
上述开发完成后,进行程序发布,发布后的文件,需要上传到主机网站空间。
上传方法,一般是通过FTP。之前我们已经申请拿到站点FTP登录信息(地址、账号和密码),这时可以通过FTP工具上传文件。当然,使用Windows文件资源管理器也可以进行上传,不过删除修改文件有时会比较麻烦,而且如果文件较大较多,容易出现连接断开。
最详细的【微信小程序+阿里云Web服务】开发部署指引(一):准备开始
最详细的【微信小程序+阿里云Web服务】开发部署指引(二):注册微信小程序
最详细的【微信小程序+阿里云Web服务】开发部署指引(三):开通阿里云主机
最详细的【微信小程序+阿里云Web服务】开发部署指引(四):搭建服务端数据库
最详细的【微信小程序+阿里云Web服务】开发部署指引(五):实现服务端调用逻辑
最详细的【微信小程序+阿里云Web服务】开发部署指引(六):开发微信小程序的准备
最详细的【微信小程序+阿里云Web服务】开发部署指引(七):小程序项目中的文件资源
最详细的【微信小程序+阿里云Web服务】开发部署指引(八):开发小程序卡片类型呈现功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(九):开发小程序卡片浏览功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(十):实现发音朗读
最详细的【微信小程序+阿里云Web服务】开发部署指引(十一):开发小程序设置功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(十二):开发小程序用户反馈功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(十三):小程序底部菜单
最详细的【微信小程序+阿里云Web服务】开发部署指引(十四):发布小程序
最详细的【微信小程序+阿里云Web服务】开发部署指引(十五):结语
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。