• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据 ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言  ASP.NET SignalR WebIM系列第二篇。本篇会带领大家将 LayIM界面中的数据动态化。当然还不涉及即时消息通讯,如果你已经搞定了数据界面,那么本文您可以简单的看一下,或者略过。

  进入正题,layim帮我们定义好了数据规则,我们只要写一个接口实现那个json规范就可以了,剩下的事情就交给layim去做,看一下json格式。(对应文件夹:demo/json/getList/.json,demo/json/getMembers.json)

  另外,大家可以参考官方文档:http://www.layui.com/doc/layim.html

{
  "code": 0
  ,"msg": ""
  ,"data": {
    "mine": {
      "username": "纸飞机"
      ,"id": "100000"
      ,"status": "online"
      ,"sign": "在深邃的编码世界,做一枚轻盈的纸飞机"
      ,"avatar": "http://cdn.firstlinkapp.com/upload/2016_6/1465575923433_33812.jpg"
    }
    ,"friend": [{
      "groupname": "前端码屌"
      ,"id": 1
      ,"online": 2
      ,"list": [{
        "username": "贤心"
        ,"id": "100001"
        ,"avatar": "http://tp1.sinaimg.cn/1571889140/180/40030060651/1"
        ,"sign": "这些都是测试数据,实际使用请严格按照该格式返回"
      },{
        "username": "Z_子晴"
        ,"id": "108101"
        ,"avatar": "http://tva3.sinaimg.cn/crop.0.0.512.512.180/8693225ajw8f2rt20ptykj20e80e8weu.jpg"
        ,"sign": "微电商达人"
      },{
        "username": "Lemon_CC"
        ,"id": "102101"
        ,"avatar": "http://tp2.sinaimg.cn/1833062053/180/5643591594/0"
        ,"sign": ""
      },{
        "username": "马小云"
        ,"id": "168168"
        ,"avatar": "http://tp4.sinaimg.cn/2145291155/180/5601307179/1"
        ,"sign": "让天下没有难写的代码"
      },{
        "username": "徐小峥"
        ,"id": "666666"
        ,"avatar": "http://tp2.sinaimg.cn/1783286485/180/5677568891/1"
        ,"sign": "代码在囧途,也要写到底"
      }]
    },{
      "groupname": "网红"
      ,"id": 2
      ,"online": 3
      ,"list": [{
        "username": "罗玉凤"
        ,"id": "121286"
        ,"avatar": "http://tp1.sinaimg.cn/1241679004/180/5743814375/0"
        ,"sign": "在自己实力不济的时候,不要去相信什么媒体和记者。他们不是善良的人,有时候候他们的采访对当事人而言就是陷阱"
      },{
        "username": "长泽梓Azusa"
        ,"id": "100001222"
        ,"sign": "我是日本女艺人长泽あずさ"
        ,"avatar": "http://tva1.sinaimg.cn/crop.0.0.180.180.180/86b15b6cjw1e8qgp5bmzyj2050050aa8.jpg"
      },{
        "username": "大鱼_MsYuyu"
        ,"id": "12123454"
        ,"avatar": "http://tp1.sinaimg.cn/5286730964/50/5745125631/0"
        ,"sign": "我瘋了!這也太準了吧  超級笑點低"
      },{
        "username": "谢楠"
        ,"id": "10034001"
        ,"avatar": "http://tp4.sinaimg.cn/1665074831/180/5617130952/0"
        ,"sign": ""
      },{
        "username": "柏雪近在它香"
        ,"id": "3435343"
        ,"avatar": "http://tp2.sinaimg.cn/2518326245/180/5636099025/0"
        ,"sign": ""
      }]
    },{
      "groupname": "我心中的女神"
      ,"id": 3
      ,"online": 1
      ,"list": [{
        "username": "林心如"
        ,"id": "76543"
        ,"avatar": "http://tp3.sinaimg.cn/1223762662/180/5741707953/0"
        ,"sign": "我爱贤心"
      },{
        "username": "佟丽娅"
        ,"id": "4803920"
        ,"avatar": "http://tp4.sinaimg.cn/1345566427/180/5730976522/0"
        ,"sign": "我也爱贤心吖吖啊"
      }]
    }]
    ,"group": [{
      "groupname": "前端群"
      ,"id": "101"
      ,"avatar": "http://tp2.sinaimg.cn/2211874245/180/40050524279/0"
    },{
      "groupname": "Fly社区官方群"
      ,"id": "102"
      ,"avatar": "http://tp2.sinaimg.cn/5488749285/50/5719808192/1"
    }]
  }
}
用户信息、好友、群组等格式

  有的同学可能觉得这个json太复杂,不知道如何下手,其实很简单,我们先分析第一层

{"code":0,"msg":"","data":null}

  是不是很简单,code就是数据是否合法,0 代表成功 1 或其他代表数据有异常,msg 就是程序上的信息,比如获取失败,或者参数不正确等等。data 最重要的一部分,就是我们下一步要分析的数据了。可以看到 data的格式如下:

{
    mine: {
        //当前登录用户的个人信息,头像,昵称等
    },
    friend: [
        //friend 第一层 是group,代表好友分组,好友分组中又包含若干好友,所以,有一个list属性,list中的每个元素肯定就是好友了,同mine一样,也包含头像,昵称等信息
    ],
    group: [
        //群组比friend相对来说简单一点,就一层,就是群组信息,至于获取群成员就要看另外一个json了。(,demo/json/getMembers.json)
    ]
}

  数据分析就做到这里,.NET当中有自带的序列化方法,也有第三方序列化组件,这里我们完全不用担心,用MVC中的JsonResult就可以了。下面我们就要开始代码阶段了,打开LayIM.Model的项目。

  好,先把最外层的写上,命名呢大致表达意思即可,在新建Model的时候要注意提取公共的字段,比如,每个对象,user 或者group都有id,那么我们就可以把id提取出来,然后写其他得类继承它就可以了。代码参考如下:

 1  /// <summary>
 2     /// 返回结果
 3     /// </summary>
 4     public class JsonResultModel
 5     {
 6         public JsonResultType code { get; set; }
 7         public object data { get; set; }
 8         public string msg { get; set; }
 9     }
10 
11     /// <summary>
12     /// 成功失败
13     /// </summary>
14     public enum JsonResultType
15     {
16         Success = 0,
17         Failed = 1
18     }
 1 /// <summary>
 2     /// 基础信息json
 3     /// </summary>
 4     public class BaseListResult
 5     {
 6         public BaseListResult()
 7         {
 8             //friend = new List<FriendGroupEntity>();
 9             //group = new List<GroupEntity>();
10         }
11         public IEnumerable<FriendGroupEntity> friend { get; set; }
12         public IEnumerable<GroupEntity> group { get; set; }
13         public UserEntity mine { get; set; }
14     }
 /// <summary>
    /// 群员信息json
    /// </summary>
    public class MembersListResult
    {
        /// <summary>
        /// 群主
        /// </summary>
        public UserEntity owner { get; set; }
        /// <summary>
        /// 群成员列表
        /// </summary>
        public IEnumerable<GroupUserEntity> list { get; set; }
    }

  其中FriendGroupEntity代表好友分组信息,GroupEntity代表群组信息,UserEntity就是用户基础信息了,这里要注意,如果增加自己的业务,比如,用户好友备注昵称,可以加字段,但是不要少了layim中规定的字段。下面贴出 UserEntity的代码,当然,也可以不用继承来实现,定义若干个类,然后每个类对应相应的对象即可。

 1  /// <summary>
 2     /// 基类
 3     /// </summary>
 4     public class BaseEntity
 5     {
 6         public int id { get; set; }
 7     }
 8 
 9     /// <summary>
10     /// 基类
11     /// </summary>
12     public class AvatarEntity : BaseEntity
13     {
14         public string avatar { get; set; } 
15     }
16 
17     /// <summary>
18     /// 用户
19     /// </summary>
20     public class UserEntity : AvatarEntity
21     {
22         public string status { get; set; }
23         public string username { get; set; }
24         public string sign { get; set; }
25     }

  好了,现在对象模型已经建好了,下一步我们该干嘛呢?没错,既然数据是活的,那么就要用到数据库了,当然这里的数据库你可以用mysql,sqlserver,mongodb等都可以。至于数据库设计就不多讲了,每个人有每个人的想法.我把表介绍一下:

  • 用户表 (包含用户基本信息,账号信息等,主键 用户id)
  • 用户好友分组表(每个用户有自己的好友分组,如果想让业务复杂一点,就加上系统分组,类似我的好友,黑名单等,这些都是不可删除的,主键 好友分组id)
  • 好友分组关系表(每个用户好友分组里面对应多个好友,外键关联 分组id,用户id)
  • 用户群表(用户加入的群或者创建的群信息,包含群主,群介绍等等,主键 群id)
  • 用户群关系表(每个群都有若干个用户,外键关联 群id,用户id)

  以上五个表我们用来对接layim基本没什么大问题了。如果有些同学确实不会设计,可以在评论区留下你的邮箱,我把脚本发给你。(这里贴图太麻烦,所以具体的设计就不在做介绍了)

 

  数据库设计完之后,就是很枯燥的CRUD了,这个不用我多说了吧,不理解的同学呢可以稍微学习一下,也不算太难。项目中我就引用了Macrosoft官方的SqlHelper,然后自己写了些帮助类。官方的sqlhelper如下:

using System;
using System.Data;
using System.Xml;
using System.Data.SqlClient;
using System.Collections;

namespace Microsoft.ApplicationBlocks.Data
{
    /// <summary>
    /// The SqlHelper class is intended to encapsulate high performance, scalable best practices for 
    /// common uses of SqlClient
    /// </summary>
    public sealed class SqlHelper
    {
        #region private utility methods & constructors

        // Since this class provides only static methods, make the default constructor private to prevent 
        // instances from being created with "new SqlHelper()"
        private SqlHelper() { }

        /// <summary>
        /// This method is used to attach array of SqlParameters to a SqlCommand.
        /// 
        /// This method will assign a value of DbNull to any parameter with a direction of
        /// InputOutput and a value of null.  
        /// 
        /// This behavior will prevent default values from being used, but
        /// this will be the less common case than an intended pure output parameter (derived as InputOutput)
        /// where the user provided no input value.
        /// </summary>
        /// <param name="command">The command to which the parameters will be added</param>
        /// <param name="commandParameters">An array of SqlParameters to be added to command</param>
        private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
        {
            if (command == null) throw new ArgumentNullException("command");
            if (commandParameters != null)
            {
                foreach (SqlParameter p in commandParameters)
                {
                    if (p != null)
                    {
                        // Check for derived output value with no value assigned
                        if ((p.Direction == ParameterDirection.InputOutput ||
                            p.Direction == ParameterDirection.Input) &&
                            (p.Value == null))
                        {
                            p.Value = DBNull.Value;
                        }
                        command.Parameters.Add(p);
                    }
                }
            }
        }

        /// <summary>
        /// This method assigns dataRow column values to an array of SqlParameters
        /// </summary>
        /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
        /// <param name="dataRow">The dataRow used to hold the stored procedure\'s parameter values</param>
        private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow)
        {
            if ((commandParameters == null) || (dataRow == null))
            {
                // Do nothing if we get no data
                return;
            }

            int i = 0;
            // Set the parameters values
            foreach (SqlParameter commandParameter in commandParameters)
            {
                // Check the parameter name
                if (commandParameter.ParameterName == null ||
                    commandParameter.ParameterName.Length <= 1)
                    throw new Exception(
                        string.Format(
                            "Please provide a valid parameter name on the parameter #{0}, the ParameterName property has the following value: \'{1}\'.",
                            i, commandParameter.ParameterName));
                if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)
                    commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];
                i++;
            }
        }

        /// <summary>
        /// This method assigns an array of values to an array of SqlParameters
        /// </summary>
        /// <param name="commandParameters">Array of SqlParameters to be assigned values</param>
        /// <param name="parameterValues">Array of objects holding the values to be assigned</param>
        private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
        {
            if ((commandParameters == null) || (parameterValues == null))
            {
                // Do nothing if we get no data
                return;
            }

            // We must have the same number of values as we pave parameters to put them in
            if (commandParameters.Length != parameterValues.Length)
            {
                throw new ArgumentException("Parameter count does not match Parameter Value count.");
            }

            // Iterate through the SqlParameters, assigning the values from the corresponding position in the 
            // value array
            for (int i = 0, j = commandParameters.Length; i < j; i++)
            {
                // If the current array value derives from IDbDataParameter, then assign its Value property
                if (parameterValues[i] is IDbDataParameter)
                {
                    IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];
                    if (paramInstance.Value == null)
                    {
                        commandParameters[i].Value = DBNull.Value;
                    }
                    else
                    {
                        commandParameters[i].Value = paramInstance.Value;
                    }
                }
                else if (parameterValues[i] == null)
                {
                    commandParameters[i].Value = DBNull.Value;
                }
                else
                {
                    commandParameters[i].Value = parameterValues[i];
                }
            }
        }

        /// <summary>
        /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters 
        /// to the provided command
        /// </summary>
        /// <param name="command">The SqlCommand to be prepared</param>
        /// <param name="connection">A valid SqlConnection, on which to execute this command</param>
        /// <param name="transaction">A valid SqlTransaction, or \'null\'</param>
        /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
        /// <param name="commandText">The stored procedure name or T-SQL command</param>
        /// <param name="commandParameters">An array of SqlParameters to be associated with the command or \'null\' if no parameters are required</param>
        /// <param name="mustCloseConnection"><c>true</c> if the connection was opened by the method, otherwose is false.</param>
        private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection)
        {
            if (command == null) throw new ArgumentNullException("command");
            if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

            // If the provided connection is not open, we will open it
            if (connection.State != ConnectionState.Open)
            {
                mustCloseConnection = true;
                connection.Open();
            }
            else
            {
                mustCloseConnection = false;
            }

            // Associate the connection with the command
            command.Connection = connection;

            // Set the command text (stored procedure name or SQL statement)
            command.CommandText = commandText;

            // If we were provided a transaction, assign it
            if (transaction != null)
            {
                if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
                command.Transaction = transaction;
            }

            // Set the command type
            command.CommandType = commandType;

            // Attach the command parameters if they are provided
            if (commandParameters != null)
            {
                AttachParameters(command, commandParameters);
            }
            return;
        }

        #endregion private utility methods & constructors

        #region ExecuteNonQuery

        /// <summary>
        /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in 
        /// the connection string
        /// </summary>
        /// <remarks>
        /// e.g.:  
        ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders");
        /// </remarks>
        /// <param name="connectionString">A valid connection string for a SqlConnection</param>
        /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
        /// <param name="commandText">The stored procedure name or T-SQL command</param>
        /// <returns>An int representing the number of rows affected by the command</returns>
        public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of SqlParameters
            return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null);
        }

        /// <summary>
        /// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string 
        /// using the provided parameters
        /// </summary>
        /// <remarks>
        /// e.g.:  
        ///  int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
        /// </remarks>
        /// <param name="connectionString">A valid connection string for a SqlConnection</param>
        /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
        /// <param name="commandText">The stored procedure name or T-SQL command</param>
        /// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
        /// <returns>An int representing the number of rows affected by the command</returns>
        public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
        {
            if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");

            // Create & open a SqlConnection, and dispose of it after we are done
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
            }
        }

        /// <summary>
        /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in 
        /// the connection string using the provided parameter values.  This method will query the database to discover the parameters for the 
        /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
        /// </summary>
        /// <remarks>
        /// This method provides no access to output parameters or the stored procedure\'s return value parameter.
        /// 
        /// e.g.:  
        ///  int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36);
        /// </remarks>
        /// <param name="connectionString">A valid connection string for a SqlConnection</param>
        /// <param name="spName">The name of the stored prcedure</param>
        /// <param name="parameterValues">An array of objects to be assigned as the input values of the stored procedure</param>
        /// <returns>An int representing the number of rows affected by the command</returns>
        public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
        {
            if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
            if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

            // If we receive parameter values, we need to figure out where they go
            if ((parameterValues != null) && (parameterValues.Length > 0))
            {
                // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
                SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName);

                // Assign the provided values to these parameters based on parameter order
                AssignParameterValues(commandParameters, parameterValues);

                // Call the overload that takes an array of SqlParameters
                return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters);
            }
            else
            {
                // Otherwise we can just call the SP without params
                return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName);
            }
        }

        /// <summary>
        /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection. 
        /// </summary>
        /// <remarks>
        /// e.g.:  
        ///  int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders");
        /// </remarks>
        /// <param name="connection">A valid SqlConnection</param>
        /// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
        /// <param name="commandText">The stored procedure name or T-SQL command</param>
        /// <returns>An int representing the number of rows affected by the command</returns>
        public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of SqlParameters
            return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null);
        }

        < 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
[转]真正理解ASP.NET的ViewState发布时间:2022-07-10
下一篇:
ASP.NET实践:定义ASP.NET主题发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap