.Net企业管理系统含源码(传智播客)

运用到的知识点:三层架构,mvc,easyui
工具:vs2010(此处有少许与教程有不同的地方),SqlServer2008
关于easyui部分,多参看demo。Jquery easyui 中文参考手册,从github里下载。
jq API参考网站:http://www.php100.com
传志博客教学视频链接:http://yun.itheima.com/course/c129.html
练习代码:https://github.com/956159241/CompanyManageFromItcast

第一步:创建三层架构

再加上web层,去掉Model层,是最基本的三层架构
基本结构

可参看:C#asp.net 三层架构简单理解

三层结构是一种严格分层方法,即数据访问层(DAL)只能被业务逻辑层(BLL)访问,业务逻辑层只能被表示层(USL)访问,用户通过表示层将请求传送给业务逻辑层,业务逻辑层完成相关业务规则和逻辑,并通过数据访问层访问数据库获得数据,然后按照相反的顺序依次返回将数据显示在表示层。有的三层结构还加了Factory、Model等其他层,实际都是在这三层基础上的一种扩展和应用.
一个简单的三层结构程序一般包括DAL BLL WEB Model几个项目,它们的相互引用关系如下

  1. WEB引用 BLL,Model
    2)BLL引用 DAL,Model
    3)DAL引用Model
    4)Model无引用

Model的作用:仅用于数据的存储而已,只不过它存储的是复杂的数据。所以如果你的项目中对象都非常简单,那么不用Model而直接传递多个参数也能做成三层架构。

注意:MVC只是在表现层。

这是我在完成了登录界面后做的一个三层架构的流程图,虽然很是片面,可以加深自己对该流程的理解,在接下来的学习中还会不断更正。推荐一个在线编辑历程图的网址:https://www.processon.com

从登录界面理解三层架构.png

MVC4下载安装:https://docs.microsoft.com/en-us/aspnet/mvc/mvc4

在安装MVC4之前需要安装一下:Microsoft Visual Studio 2010 Service Pack 1 (Installer)

安装VS 2010 sp1
路漫漫其修远兮……
终于安装好了

安装好了,可是MVC4在新建项目里却不显示!!!奇怪!!!


更改一下.net framework 的版本再看看……


创建mvc4的web项目


再添加一个类库,存放公共工具。



ok,三层架构搭建完成了。

第二步:创建数据库

2.1 创建UserInfo表


设置Id为主键,自动增长;
并为RegTime添加自动添加为当前时间并且在SQL Server中设置时间格式

--为RegTime设置为当前时间
ALTER TABLE dbo.UserInfo
    ADD CONSTRAINT DFT_UserInfo_RegTime
    DEFAULT(CURRENT_TIMESTAMP) FOR RegTime;

查询语句:

--查询UserInfo里的数据
SELECT Id,UserName,UserPwd,UserMail,CONVERT(NVARCHAR(50),RegTime,111) AS RegTime
    FROM dbo.UserInfo;
查询结果

2.2 创建News表

News

设置Id为主键,自动增长。把Msg的text改成ntext。设置SubDateTime为当前时间。

2.3 创建NewsComments表

NewsComments

设置Id为主键,自动增长。设置CreateDateTime为当前时间。

其实这些当前时间也可以在插入数据的时候使用getdate()函数获取插入,我这么写之后便不用插入这一列,会默认插入。

第三步:为Model添加类

3.1 为UserInfo表创建一个实体类(可使用代码生成工具)

第四步:为数据层添加类

4.1 准备工作,添加连接数据库字符串和添加引用类

首先引用Iotzzh.CMS.Model类



然后在webconfig里添加链接字符串:

  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-Iotzzh.CMS.Webapp-20170410084318;Integrated Security=SSPI" />
    <add name="connStr" connectionString="server=.;uid=sa;pwd=0301;database=Iotzzh.CMS" />
  </connectionStrings>

4.2 添加SqlHelper类

为ConfigurationManager添加引用类:



SqlHelper.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;


namespace Iotzzh.CMS.DAL
{
    //数据处理采用的ado.net
    public class SqlHelper
    {
        private static readonly string connString = ConfigurationManager.ConnectionStrings
            ["connStr"].ConnectionString;
        //添加一个查询
        public static DataTable GetTable(string sql, CommandType type, params SqlParameter[] pars)
        {
            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlDataAdapter apter = new SqlDataAdapter(sql, conn))
                {
                    apter.SelectCommand.CommandType = type;
                    if (pars != null)
                    {
                        apter.SelectCommand.Parameters.AddRange(pars);
                    }
                    DataTable da = new DataTable();
                    apter.Fill(da);
                    return da;
                }
            }
        }
        public static int ExecuteNonquery(string sql,CommandType type,params SqlParameter[] pars)
        {
            using(SqlConnection conn = new SqlConnection(connString))
            {
                using(SqlCommand cmd = new SqlCommand(sql,conn))
                {
                    cmd.CommandType = type;
                    if (pars != null)
                    {
                        cmd.Parameters.AddRange(pars);
                    }
                    conn.Open();
                    return cmd.ExecuteNonQuery();
                }
            }
        }
    }
}

第五步:添加登录界面

在Webapp下的Controlers下添加LoginController,注意此处在命名的时候,Controller不能去掉,体现出来约定大于配置的一种思想。

5.1 为index添加一个视图:

更改路由方式Iotzzh.Webapp-->Global.asax-->RoutConfig.cs然后修改Home为自己指定的路径。

指定路径

注意:Images,css放置在content下:

由于此次的学习侧重点不同,涉及到的界面就不再自己布局。路由改好了,图片添加好了,运行下:


验证码功能放入到公共工具类库(Common)中:


为Common添加应用,System.Drawing和System.Web。


引用Drawing

引用web

生成一下。

那如何调用这个方法呢?
找到webapp下的LoginControler:

  • 1 在mvc这个项目里引用Common
  • 2 添加引用方法
 //调用分装验证码的类
        public ActionResult ShowValidateCode()
        {
            Itcast.CMS.Common.ValidateCode validateCode = new Itcast.CMS.Common.ValidateCode();
            string code = validateCode.CreateValidateCode(4);//获取验证码.
            Session["code"] = code;
            byte[] buffer = validateCode.CreateValidateGraphic(code);
            return File(buffer, "image/jpeg");
        }

这个地方,教程用的Common,可是我用却不行,只能使用完整的应用路径。

5.2 Index.cshtml 详解

前台代码一:

      <head>   
          <script type="text/javascript">
        if (window.parent.window != window) {
            window.top.location.href = "/Home/CheckLogin";
        }
          </script>
        </head>

前台代码二:

    <script src="~/Scripts/jquery-1.7.1.min.js"></script>       
          <script type="text/javascript">
        function changeCheckCode() {
            $("#img").attr("src", $("#img").attr("src") + 1);  //id=2
        }
      </script>

这段代码用于更换验证码的显示,每次点击,将img的src更换。
前台代码三:

 @*mvc提供的ajax异步表单*@
          <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
  function afterLogin(data) {
            var serverData = data.split(':');
            if (serverData[0] == "ok") {
                window.location.href = "/Home/Index";
            } else if (serverData[0] == "no") {
                $("#errorMsg").text(serverData[1]);
                changeCheckCode();
            } else {
                $("#errorMsg").text("系统繁忙!!");
            }

        }

代码三首先将后台(控制器中返回)返回的数据进行分割。获取到ok或no;如果是ok,则进行页面跳转,如果是no,则显示系统繁忙。

前台代码四(表单代码):

 @using(Ajax.BeginForm("UserLogin",new{},new AjaxOptions(){ HttpMethod="post", OnSuccess="afterLogin"},new{id="loginForm"})){
                    <table cellpadding="0" cellspacing="0">
                        <tbody>
                            <tr>
                                <td align="left" colspan="2">
                                    <h3>
                                        请使用IotzzhCMS系统账号登录</h3>
                                </td>
                            </tr>
                            <tr>
                                <td align="right">
                                    账号:
                                </td>
                                <td align="left">
                                    <input type="text" name="LoginCode" id="LoginCode" class="login-text" />
                                   
                                </td>
                            </tr>
                            <tr>
                                <td align="right">
                                    密码:
                                </td>
                                <td align="left">
                                    <input type="password" name="LoginPwd" id="LoginPwd" value="123" class="login-text" />
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    验证码:
                                </td>
                                <td align="left">
                                    <input type="text" class="login-text" id="code" name="vCode" value="1" />
                                </td>
                            </tr>
                            <tr>
                                <td>
                                </td>
                                <td>
                                    ![](/Login/ShowValidateCode/?id=1)
                                    <div style="float: left; margin-left: 5px; margin-top: 10px;">
                                        <a href="javascript:void(0)" onclick="changeCheckCode();return false;">看不清,换一张</a>
                                    </div>
                                </td>
                            </tr>
                            <tr>
                                <td align="center" colspan="2">
                                    <input type="submit" id="btnLogin" value="登录" class="login-btn" />
                                    <span id="errorMsg"></span>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    }

分解:

  ![](/Login/ShowValidateCode/?id=1)
                                    <div style="float: left; margin-left: 5px; margin-top: 10px;">
                                        <a href="javascript:void(0)" onclick="changeCheckCode();return false;">看不清,换一张</a>

这个地方使用的调用更改验证码的一个方法,就不多说了。

 @using(Ajax.BeginForm("UserLogin",new{},new AjaxOptions(){ HttpMethod="post", OnSuccess="afterLogin"},new{id="loginForm"})){
表单
}

这个是采用mvc提供的一个异步表单操作。把数据提交到后台的UserLogin方法里,前台的方法是afterLogin。

5.3 < UserLogin >通过接收到ajax传来的数据,LoginControler里的方法编写

5.3.1 首先在控制器里写UserLogin方法
//通过Ajax获取前台传入的数据
        public ActionResult UserLogin()
        { 
            //首先判断已给的验证处是否为空
            string validateCode = Session["code"] == null? string.Empty:
                Session["code"].ToString();
            //如果已给的验证码为空,提示!
            if (string.IsNullOrEmpty(validateCode))
            {
                return Content("no:验证码错误");
            }
            //此时的session已经赋值给了validateCode,所以可以清空了
            Session["code"] = null;
            //获取用户输入的验证码
            string txtCode = Request["vCode"];
            //判断,如果系统的验证码与用户输入的验证码不一致,则提示
            if (!validateCode.Equals(txtCode, StringComparison.InvariantCultureIgnoreCase))
            {
                return Content("no:验证码错误");
            }
            string userName = Request["LoginCode"];
            string userPwd = Request ["LoginPwd"];

注释:这里已经获取前台输入的数据;然后进入逻辑层,对数据进行操作-->5.3.2 UserInfoService.cs

            UserInfoService userInfoService = new UserInfoService();
            UserInfo userInfo = userInfoService.GetUserInfo(userName,userPwd);
            if (userInfo != null)
            {
                Session["userInfo"] = userInfo;
                return Content("ok:登录成功!");
            }
            else 
            {
                return Content("no:登录失败!");
            }


        }
5.3.2 逻辑层处理数据,UserInfoService.cs,返回用户名和密码--》Controler下的UserLogin
 public class UserInfoService
    {
        DAL.UserInfoDal UserInfoDal = new DAL.UserInfoDal();
        public UserInfo GetUserInfo(string userName, string userPwd)
        {

注释:此处需要获取数据库里的数据;---》数据访问层DAL---》5.3.3 UserInfoDal

            return UserInfoDal.GetUserInfo(userName,userPwd);
        }
    }
5.3.3 数据访问层 UserInfoDal(查询验证),如果验证成功,获取用户信息并返回——》UserInfoServices.cs
public UserInfo GetUserInfo(string userName,string userPwd)
        {
            string sql = "select * from UserInfo where UserName = @UserName" + 
                " and UserPwd = @UserPwd";
            SqlParameter[] pars = {
                                    new SqlParameter("@UserName",SqlDbType.NVarChar,50),
                                    new SqlParameter("@UserPwd",SqlDbType.NVarChar,50)
                                 };
            pars[0].Value = userName;
            pars[1].Value = userPwd;
            DataTable da = SqlHelper.GetTable(sql, CommandType.Text, pars);
            UserInfo userInfo = null;
            if (da.Rows.Count > 0)
            {
                userInfo = new UserInfo();
                LoadEntity(userInfo,da.Rows[0]);
            }
            return userInfo;
        }
        public void LoadEntity(UserInfo userInfo, DataRow row)
        {
            userInfo.Id = Convert.ToInt32(row["Id"]);
            //判断是否为空,对于上面的Id也可以做此操作,由于设置了主键不会为空的
            //就没有必要执行这一步了
            userInfo.UserName = row["UserName"] != DBNull.Value?
                row["UserName"].ToString():string.Empty;
            userInfo.UserPwd = row["UserPwd"] != DBNull.Value ?
                row["UserPwd"].ToString() : string.Empty;
            userInfo.UserMail = row["UserMail"] != DBNull.Value ?
                row["UserMail"].ToString() : string.Empty;
            userInfo.RegTime = Convert.ToDateTime(row["RegTime"]);
        }

5.4 登录界面的运行展示

登录界面

第六步 添加Home页面

6.1 先创建一个控制器HomeControler然后创建Home视图。

拷贝jq里面的theams到webapp下的content下(里面包含css样式和图标等):


添加jq和easyUI的引用,这里如果右侧的script里面没有需要自行下载导入:


看一下基本界面:



然后填充一下左侧和底部的内容。


6.2 在右侧区域(核心区域添加一个表格,显示新闻列表)

首先,为核心的新闻列表内容添加Controler(控制器)和view(视图)。
然后在区域内添加一个tabs,里面嵌入一个iframe,引入AdminNewList/Index。
为左侧的超链接添加点击事件,右侧随左侧的点击更换iframe的地址。



js代码:

<script type="text/javascript">
        $(function () {
            binClickEvent();
        });
        function binClickEvent() {
            //绑定超链接的单击事件
            $(".detailLink123").click(function () {
                var title = $(this).text();
                var url = $(this).attr("url");
                var isExt = $('#tt').tabs('exists', title);//判断页签是否存在
                if (isExt) {
                    $('#tt').tabs('select', title);
                    return;
                }

                $('#tt').tabs('add', {
                    title: title,
                    content: showContent(url),
                    closable: true
                });

            });
        }
        //页签中显示的内容
        function showContent(url) {
            var strHtml = '<iframe src="' + url + '" scrolling="no" width="100%" height="100%" frameborder="0"></iframe>';
            return strHtml;
        }
        
    </script>

html代码:

        <div class="easyui-tabs" style="width:700px;height:250px" fit="true" id="tt">
            <div title="新闻管理" style="padding:10px">
                <iframe src="/AdminNewList/Index" scrolling="no" width="100%" height="100%" frameborder="0"></iframe>
            </div>
    </div>

最后就是为右侧添加分页的数据内容了:数据库查询——>分页

6.3 从数据库内获取数据,并进行分页

第一步:在Model层内添加实体类
NewInfo.cs

namespace Iotzzh.CMS.Model
{
    public class NewInfo
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Msg { get; set; }
        public DateTime SubDateTime { get; set; }
        public string Author { get; set; }
        public string ImagePath { get; set; }
    }
}

第二步:在DAL层内新建类(NewInfoDal),获取数据并进行分页

namespace Iotzzh.CMS.DAL
{
    public class NewInfoDal
    {
        //定义一个集合,一个获取分页的方法,由BLL(业务逻辑)层传入start和end
        public List<NewInfo> GetPageList(int start, int end)
        {
            string sql = "select * from (select row_number() over (order by id) as" + 
                "num,* from News ) as t where t.num >=@start adn t.num <= @end";
            SqlParameter[] pars = {
                                    new SqlParameter("@start",SqlDbType.Int),
                                    new SqlParameter("@end",SqlDbType.Int)
                                 };
            pars[0].Value = start;
            pars[1].Value = end;
            //进行查询
            DataTable da = SqlHelper.GetTable(sql,CommandType.Text,pars);
            //声明集合
            List<NewInfo> list = null;
            if (da.Rows.Count > 0)
            { 
                //把datatable里的数据放到list里返回就可以了
                list = new List<NewInfo>();
                NewInfo newInfo = null;
                //遍历所有的行
                foreach (DataRow row in da.Rows)
                {
                    newInfo = new NewInfo();
                    //加载一下
                    LoadEntity(row,newInfo);
                    //把newInfo放到list集合里面
                    list.Add(newInfo);


                }
            }
            return list;
        }
        public void LoadEntity(DataRow row, NewInfo newInfo)
        {
            newInfo.Id = Convert.ToInt32(row["Id"]);
            newInfo.Author = row["Author"] != DBNull.Value ? 
                    row["Author"].ToString() : string.Empty;
            newInfo.Title = row["Title"] != DBNull.Value ?
                    row["Title"].ToString() : string.Empty;
            newInfo.Msg = row["Msg"] != DBNull.Value ?
                    row["Msg"].ToString() : string.Empty;
            newInfo.SubDateTime = Convert.ToDateTime(row["SubDateTime"]);
            newInfo.ImagePath = row["ImagePath"] != DBNull.Value ?
                    row["ImagePath"].ToString() : string.Empty;
        }
/// <summary>
        /// 获取总的记录数
        /// </summary>
        /// <returns></returns>
        public int GetRecordCount()
        {
            string sql = "select count(*) from News";
            return Convert.ToInt32(SqlHelper.ExecuteScalare(sql,CommandType.Text));
        }
    }
}

第三步:为BLL层添加类()

namespace Iotzzh.CMS.BLL
{
    
    public class NewInfoService
    {
        DAL.NewInfoDal NewInfoDal = new DAL.NewInfoDal();
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex">当前页码值</param>
        /// <param name="pageSize">每页显示记录数</param>
        /// <returns></returns>
        public List<NewInfo> GetPageList(int pageIndex, int pageSize)
        {
            int start = (pageIndex - 1) * pageSize + 1;
            int end = pageIndex * pageSize;
            List<NewInfo> list = NewInfoDal.GetPageList(start,end);
            return list;
        }
        /// <summary>
        /// 获取总的页数
        /// </summary>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public int GetPageCount(int pageSize)
        {
            int recordCount = NewInfoDal.GetRecordCount();
            int pageCount = Convert.ToInt32(Math.Ceiling((double)recordCount/pageSize));
            return pageCount;
        }
    }
}

业务逻辑层和数据访问层都处理好了,现在可以在显示层(AdminNewListControler)调用了。
第四步:Controler调用BLL层并向View里传递数据

namespace Iotzzh.CMS.Webapp.Controllers
{
    public class AdminNewListController : Controller
    {
        //
        // GET: /AdminNewList/
        BLL.NewInfoService NewInfoService = new BLL.NewInfoService();
        public ActionResult Index()
        {
            int pageIndex = Request["pageIndex"]!= null?int.Parse(Request["pageIndex"]):1;
            int pageSize = 5;
            int pageCount = NewInfoService.GetPageCount(pageSize);
            pageIndex = pageIndex < 1 ? 1 : pageIndex;
            pageIndex = pageIndex > pageCount ? pageCount : pageIndex;
            List<NewInfo> list = NewInfoService.GetPageList(pageIndex,pageSize);
            //通过ViewData将数据传递到前端视图里面
            ViewData["list"] = list;
            ViewData["pageIndex"] = pageIndex;
            ViewData["pageCount"] = pageCount;
            return View();
        }

    }
}

第五步:view获取数据并显示
AdminNewList/index

@using Iotzzh.CMS.Model
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width" />
    <title>AdminNewList</title>
    <link href="../../Content/tableStyle.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div>
    @if (ViewData["list"] != null)
    {
       <table width="60%">
            <tr>
                <th>编号</th>
                <th>标题</th>
                <th>作者</th>
                <th>时间</th>
                <th>详细</th>
            </tr>
            @foreach (NewInfo newInfo in (List<NewInfo>)ViewData["list"])
            { 
                <tr>
                    <td>@newInfo.Id</td>
                    <td>@newInfo.Title</td>
                    <td>@newInfo.Author</td>
                    <td>@newInfo.SubDateTime</td>
                    <td>详细</td>
                </tr>
            }
       </table>
    }
    else
    { 
    <span>暂无数据</span>
    }
    </div>
</body>
</html>


第六步:添加分页方式与分页标签
首先,添加一个公共类:PageBar.cs

namespace Iotzzh.CMS.Common
{
    public class PageBar
    {
        /// <summary>
        /// 产生数字页码条。
        /// </summary>
        /// <param name="pageIndex">当前页码值</param>
        /// <param name="pageCount">总的页数</param>
        /// <returns></returns>
        public static string GetPageBar(int pageIndex, int pageCount)
        {
            if (pageCount == 1)
            {
                return string.Empty;
            }
            int start = pageIndex - 5;//起始位置,要求页面上显示10个数字页码
            if (start < 1)
            {
                start = 1;
            }
            int end = start + 9;//终止位置
            if (end > pageCount)
            {
                end = pageCount;
            }
            StringBuilder sb = new StringBuilder();
            for (int i = start; i <= end; i++)
            {
                if (i == pageIndex)
                {
                    sb.Append(i);
                }
                else
                {
                    sb.Append(string.Format("<a href='?pageIndex={0}'>{0}</a>", i));
                }
            }
            return sb.ToString();
        }
    }
}

然后再view/index里面引用

 <p>
            @MvcHtmlString.Create(PageBar.GetPageBar((int)ViewData["pageIndex"],(int)ViewData["pageCount"]))
        </p>

这里的pageIndex和pageCount是由在Contoler里面获取的



6.4 为详情添加弹出信息框


这里可能很多是重复的,主要是为了加深个人对整个过程的理解。
第一步:相应的引入还是必须有的:

    <link href="~/Content/tableStyle.css" rel="stylesheet" />
    <link href="~/Content/pageBar.css" rel="stylesheet" />
    <link href="~/Content/themes/default/easyui.css" rel="stylesheet" />
    <link href="~/Content/themes/icon.css" rel="stylesheet" />
    <script src="~/Scripts/jquery-1.7.1.min.js"></script>
    <script src="~/Scripts/jquery.easyui.min.js"></script>
    <script src="~/Scripts/easyui-lang-zh_CN.js"></script>

第二步:在table里添加一个标题列:

           <tr>
                <th>编号</th>
                <th>标题</th>
                <th>作者</th>
                <th>时间</th>
                <th>详细</th>
                <th>删除</th>
            </tr>

第三步:在信息内容里提添加一列:

 @foreach (NewInfo newInfo in (List<NewInfo>)ViewData["list"])
            { 
                <tr>
                    <td>@newInfo.Id</td>
                    <td>@newInfo.Title</td>
                    <td>@newInfo.Author</td>
                    <td>@newInfo.SubDateTime</td>
                    <td ><a href="javascript:void(0)" class="details" ids = "@newInfo.Id">详细</a></td>
                    <td ><a href="javascript:void(0)" class="delete" ids = "@newInfo.Id">删除</a></td>
                </tr>
            }

第四步:链接添加好了,把弹出框以及里面的内容布局一下

<!------------------------------显示详细信息内容-------------------------------------->
    <div id="detailDiv">
        <table>
            <tr><td>标题</td><td><span id="title"></span></td></tr>
            <tr><td>作者</td><td><span id="author"></span></td></tr>
            <tr><td>时间</td><td><span id="subDateTime"></span></td></tr>
            <tr><td>内容</td><td><span id="msg"></span></td></tr>
        </table>
    </div>

    <!------------------------------显示详细信息内容结束-------------------------------------->

第五步:有了一个盒子,可是怎么把数据填充进来呢?这里就用到异步了:
首先,先将detailDiv进行隐藏,然后为详情添加点击事件:

 $("#detailDiv").css("display", "none");
            $(".details").click(function () {
                showDetail($(this).attr("ids"));
            });

接下来就是ShowDetail的方法代码编写了:

//显示详细信息
        function showDetail(id) {
            $.post("/AdminNewList/GetNewInfoModel", { "id": id }, function (data) {
                $("#title").text(data.Title);
                $("#author").text(data.Author);
                $("#subDateTime").text(ChangeDateFormat(data.SubDateTime));
                $("#msg").text(data.Msg);
            });
            $("#detailDiv").css("display", "block");
            //EasyUI的弹出框样式的使用
            $("#detailDiv").dialog({
                modal: true,
                resizable: true,
                maximizable: true,
                collapsible: true,
                title: "新闻详细",
                width: 400,
                height: 200,
                buttons: [{
                    text: '确定',
                    iconCls: 'icon-ok',
                    handler: function () {
                        alert('ok');
                    }
                }, {
                    text: '取消',
                    handler: function () {
                        $('#detailDiv').dialog('close');
                    }
                }]
            });
        }

这个方法里的核心代码:

  $.post("/AdminNewList/GetNewInfoModel", { "id": id }, function (data) {
                $("#title").text(data.Title);
                $("#author").text(data.Author);
                $("#subDateTime").text(ChangeDateFormat(data.SubDateTime));
                $("#msg").text(data.Msg);
            });

将数据赋值到每个指定的容器里,下面的代码是之前用的ajax获取异步请求的代码:

 $.ajax({
                    url: "UsersManageHandler.ashx",
                    type: "POST",
                    data: { name: name, password: password },
                    success: function (data) {
                        if (data != '') {
                            alert(data);
                        } else {
                            location.reload();
                        }
                    }

                }

                );
$.post
$.Ajax 看着简单,内有乾坤

可参看网站:http://www.php100.com/manual/jquery/ 进行更多的了解
貌似扯远了,通过上面的代码,很容易看出,将id传入到GetNewInfoModel(一般处理程序,Controler内,AdminNewList下的方法),简单说,就是传参获取数据库内的整行内容。

注意:这里的使用AdminNewList下的方法,"/AdminNewList/GetNewInfoModel"

第六步:编辑显示层的Controler下的AdminNewLIst里的GetNewInfoModel方法。由于在界面里面传入的data是id,所以首先先接收一下数据,然后对Model里的NewInfo实例化,获取BLL层GetModel方法,并处理id参数。最后经过Json序列化返回。

  #region 获取详细信息
        public ActionResult GetNewInfoModel()
        {
            int id = int.Parse(Request["id"]);
            NewInfo newInfo = NewInfoService.GetModel(id);
            //把数据序列化
            return Json(newInfo,JsonRequestBehavior.AllowGet);
        }

        #endregion

这里在Model里的NewInfo就不作解释了,然后看看GetMmodel(id);
第七步:BLL层的功能

         /// <summary>
        /// 通过web层传来的id,通过使用dal层的方法,返回结果
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public NewInfo GetModel(int id)
        {
            return NewInfoDal.GetModel(id);
        }

第八步:DAL层功能

         /// <summary>
        /// 获取一条记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public NewInfo GetModel(int id)
        {
            string sql = "select * from News where id = @id";
            SqlParameter[] pars = { 
                                    new SqlParameter("@id",SqlDbType.Int)
                                  };
            pars[0].Value = id;
            DataTable da = SqlHelper.GetTable(sql,CommandType.Text,pars);
            NewInfo newInfo = null;
            if (da.Rows.Count > 0)
            {
                newInfo = new NewInfo();
                LoadEntity(da.Rows[0], newInfo);
            }
            return newInfo;
        }

这里的第几步只是用作代码理解用,编写的时候,在写界面层的时候,就想到要获取一个数据,然后到DAL层编写一个获取一条信息的方法,然后在BLL调用DAL里的方法,将数据返回到显示层,最后编写Controler里的内容,获取数据,返回数据。突然在想,这么多层,如何正确的区分什么功能代码正确的写到对应的地方呢,BLL层如果省去了貌似也可以,为什么非要加一个BLL层在中间碍事呢?回头再看看三层架构的优势:三层架构的简单理解

6.5 添加删除功能

添加删除的功能的方法与上述的方法是一样的,就不再重述了,贴上核心代码:
web层:

$(".delete").click(function () {
                deleteInfo($(this).attr("ids"), $(this));
            });
//删除新闻
        function deleteInfo(id, control) {
            $.messager.confirm('提示', '确定删除该记录么?', function (r) {
                if (r) {
                    //发送异步请求
                    $.post("/AdminNewList/DeleteNewInfo", {"id":id},function(data){
                        if(data == "ok"){
                           $(control).parent().parent().remove();
                           $.messager.alert("提示:","删除成功","info");

                        }else{
                            $.messager.alert("提示:","删除失败","info");
                       }
                    });
#region 删除信息
        public ActionResult DeleteNewInfo()
        {
            int id = int.Parse(Request["id"]);
            if (NewInfoService.DeleteInfo(id))
            {
                return Content("ok");
            }
            else
            {
                return Content("Error");
            }
        }

        #endregion

BLL层:

 public bool DeleteInfo(int id)
        {
            return NewInfoDal.DeleteInfo(id) > 0;      
        }

DAL层:

/// <summary>
        /// 删除一条记录
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int DeleteInfo(int id)
        {
            string sql = "delete from News where id = @id";
            return SqlHelper.ExecuteNonquery(sql,CommandType.Text,new SqlParameter("@id",id));
        }

6.6 添加添加功能


注意:这里给的文件上传插件貌似并不能在这里使用,但是文本的上传却可以使用,个人认为很有可能是使用.framework版本比教程低的缘故,这里无法实现局部上传也无法实现获取图片地址,个人能力有限,无法对该插件进行适应性的操作,暂且将图片的路径设置成一个固定值,也不实现真正图片上传功能。在这里先主要学习一下在三层里面插入数据。不过插件自带的富文本编辑器里带图片上传是可以实现的。所以具体的什么原因还不是很清楚。
第一步:DAL层

 /// <summary>
        /// 添加一条记录
        /// </summary>
        /// <param name="newInfo"></param>
        /// <returns></returns>
        public int AddInfo(NewInfo newInfo)
        {
            string sql = "insert into News(Author,Title,Msg,ImagePath,SubDateTime)" +
            "values(@Author,@Title,@Msg,@ImagePath,@SubDateTime)";
            SqlParameter[] pars = {
                                    new SqlParameter("@Author",SqlDbType.NVarChar,50),
                                    new SqlParameter("@Title",SqlDbType.NVarChar,50),
                                    new SqlParameter("@Msg",SqlDbType.NText),
                                    new SqlParameter("@ImagePath",SqlDbType.NVarChar,500),
                                    new SqlParameter("@SubDateTime",SqlDbType.DateTime)
                                  };
            pars[0].Value = newInfo.Author;
            pars[1].Value = newInfo.Title;
            pars[2].Value = newInfo.Msg;
            //pars[3].Value = newInfo.ImagePath;
            pars[3].Value = "D:mypic";
            pars[4].Value = newInfo.SubDateTime;

            return SqlHelper.ExecuteNonquery(sql,CommandType.Text,pars);
        }

第二步:BLL层

public bool AddInfo(NewInfo newInfo)
        {
            return NewInfoDal.AddInfo(newInfo) > 0;
        }

第三步:显示层,这里由于文件上传无法使用,controler就没起到作用,直接用的mvc下的ajax异步提交。那个插件的用处就是可以为内容文字添加一些样式。在此也就忽略不记。
核心代码:

  @using (Ajax.BeginForm("AddNewInfo", "AdminNewList", new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterAdd" }, new {id="form1" }))
        {
        <table>
            <tr><td>新闻名称</td><td><input type="text" name="Title" /></td></tr>
             <tr><td>作者</td><td><input type="text" name="Author" /></td></tr>
               <tr><td>上传图片</td><td>
                   <input type="file" name="fileUp" id="fileUpImage" />
                   <input type="submit" value="上传图片" id="btnFileUp" />
                   <input type="hidden" id="hidImagePath" name="ImagePath" />
                   <div id="showImage">

                   </div>

                                </td></tr>
               <tr><td>新闻内容</td><td>
                    <textarea id="MsgContent" cols="100" rows="8" style="width: 500px; height: 

200px; visibility: hidden;" name="Msg"></textarea>


                                </td></tr>
        </table>
        }

通过此段代码来输入数据。
技巧:如何通过点击确定,关闭该窗口的。
首先,在Index.cshtml下加入函数:

 //添加完成以后调用该方法关闭添加窗口
        function afterAdd() {
            $('#divAdd').dialog('close');//jq-easyui方法
        }

然后在ShowAddInfo.cshtml

 //提交表单
        function subForm() {
            $("#form1").submit();
        }
      //调用父页面方法
        function afterAdd() {
            window.parent.afterAdd();
        }





如果觉得文章写得还行,请点个赞。如果想与我进一步交流,可以关注我的公众号或者加我的微信。

个人微信

公众号_DotNet微说.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容