• [转]EasyUI+MVC+EF简单用户管理Demo(问题及解决)


    写在前面

    1. iframe-src

    2. EntityFramework版本

    3. connectionStrings

    4. View、Action、页面跳转

    5. EasyUI中DataGrid绑定

    6. 新增、修改和删除数据

    7. 效果图、完整示例Demo下载

    8. 后记

      关于EasyUI了解差不多,就想结合MVC、EF做一个简单的用户管理Demo,其实没多少东西,但这是小菜我第一次做。主要是熟悉下其中的流程,当然也遇到一些问题,走了很多的弯路。

      Demo做的过程就不详细描述了,大家可以在文章后面下载下来看下,这边就只记录下在做的过程中遇到的一些问题和解决方式,希望可以帮到像我一样的小菜,也欢迎大神指点。

      自己动手,丰衣足食。

    iframe-src

      Easyui左边菜单链接到内容区域的tab,tab页面一般用的是iframe,在ASP.NET我们一般使用下面这样的src:

    1 <iframe scrolling="auto" frameborder="0"  src="Home.html" style="100%;height:100%;"></iframe>

      在MVC中如果直接使用这样的src链接会找不到页面地址,我们需要这样做:

    1 <iframe scrolling="auto" frameborder="0"  src="Home/GetView?viewPara=Home" style="100%;height:100%;"></iframe>

      src格式是“{controller}/{action}?viewPara={ViewName}”,控制器代码:

    复制代码
    1         /// <summary>
    2         /// iframe获取视图
    3         /// </summary>
    4         /// <returns></returns>
    5         public ActionResult GetView(string viewPara)
    6         {
    7             return View(viewPara);
    8         }
    复制代码

      如果填写的ViewName不是在本目录下,要填写相对目录比如:src="Home/GetView?viewPara=../User/User_List“。

    EntityFramework版本

      关于这个问题,这边我要详细的描述下,虽然最后解决方式很简单,但是在找出这个问题的时候花了我好几个小时,很是郁闷。

      MVC我们提交表单一般是用Aajx,如下登陆提交表单检查账号:

    复制代码
     1             $.ajax({
     2                 url: "Login/CheckUserLogin",
     3                 type: "POST",
     4                 dataType: "json",
     5                 data: { "Name": $("#UserName").val(), "Password": $("#Password").val() },
     6                 //contentType: "application/json",
     7                 success: function (data) {
     8                     if (data.result == "success") {
     9                         window.location.href = "/Home/Index";
    10                     }
    11                     else {
    12                         alert(data.content);
    13                         window.location.href = "/Login/Login/";
    14                     }
    15                 },
    16                 error: function (xhr, error, ex) {
    17                     alert("出现错误,请稍后再试,带来不便,敬请谅解");
    18                     window.location.href = "/Login/Login/";
    19                 }
    20             });
    复制代码

      可以看出js代码没什么问题,从URL看出是提交到Login控制器的CheckUserLogin,那我们代码可以这样写:

    复制代码
     1         /// <summary>
     2         /// 处理登录的信息
     3         /// </summary>
     4         /// <param name="userInfo"></param>
     5         /// <returns></returns>
     6         public JsonResult CheckUserLogin(UserInfo userInfo)
     7         {
     8             //return Json(new { result = "error", content = "用户名密码错误,请您检查" });
     9             using (EasyUIDemoDBEntities db = new EasyUIDemoDBEntities())
    10             {
    11                 //linq查询
    12                 var users = from p in db.UserInfo
    13                             where p.Name == userInfo.Name && p.Password == userInfo.Password && p.Enable == true
    14                             select p;
    15                 if (users.Count() > 0)
    16                 {
    17                     userInfo = users.FirstOrDefault();
    18                     Response.Cookies["UserName"].Value = userInfo.Name;
    19                     Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(7);
    20                     return Json(new { result = "success", content = "" });
    21                 }
    22                 else
    23                 {
    24                     return Json(new { result = "error", content = "用户名密码错误,请您检查" });
    25                 }
    26             }
    27         }
    复制代码

      EasyUIDemoDBEntities是我们创建模型的上下文,从代码上可以看出也没什么问题,那我们在第十行设置个断点,运行一下:

      上面报的是“Internal Server Error”错误,我们上面在CheckUserLogin方法中设置的断点根本没有执行到,网上找了很多的资料,但是没有没能找到方式解决,我原本以为是Ajax提交问题,然后改成Get提交,把using里的代码屏蔽掉是可以的,那就说明Ajax没什么问题。

      回到Internal Server Error这段话,从字面上理解是主机服务器问题,网上说是后台代码问题,当时没怎么注意,心想没什么问题啊,最后实在找不到其他原因,就新建一个控制台程序,把using里面的代码复制过去,运行一下,报下面错误:

      从上面调试的结果看出,我们离真相越来越近了,也说明一点:不要太相信自己的代码。从异常上可以看出是EntityFramework版本问题。

      第一个是控制台程序的EntityFramework版本,第二个是实例模型的EntityFramework版本,因为我们创建控制台程序的时候,NuGget添加程序包EntityFramework是添加的最新版本,而新建实体模型的时候,添加的是4.4版本,我们把EntityFramework版本修改一致就可以了。

    connectionStrings

      上面的问题解决了,我们就可以调试代码了,但是下面又出现这样的问题:

      异常表示找不到EasyUIDemoDBEntities连接字符串,但是我们创建的实体模型App.Config文件中是有EasyUIDemoDBEntities连接字符串的,网上搜了一下,说是要在主程序也要加连接字符串,MVC添加EasyUIDemoDBEntities连接字符串后,运行OK。

    View、Action、页面跳转

      解决完iframe的src有关后,我们现在要这样做:登录输入用户名和密码,如果正确的话跳转到主界面,关于MVC中js跳转页面我们可以这样写:

    1       //window.location.href = "Home/GetView?viewPara=Index";
    2       //window.location.href = "@Url.Content("/Home/Index/")";
    3       window.location.href = "/Home/Index";

      Home表示Controller,Index表示Action,主界面的src还是按照我们上面解决方式写,跳转到主界面会出现下面这种情况:

      我们如果改下路由直接浏览主界面,是可以正常浏览的,但是从上面可以看出iframe的src根本没有执行到Home控制器,网上也没搜到相关资料,最后在Home控制器添加下面代码就好了:

    1         public ActionResult Home()
    2         {
    3             return View();
    4         }

      不知是什么情况?再做个试验:我们再主界面的主页这样写:

    1 <iframe scrolling="auto" frameborder="0"  src="Home/GetView?viewPara=../User/User_Add" style="100%;height:100%;"></iframe>

       src不指向Home,而指向User目录下的User_Add,Home控制器代码:

    复制代码
     1         public ActionResult Index()
     2         {
     3             return View();
     4         }
     5         public ActionResult Home()
     6         {
     7             return View();
     8         }
     9         /// <summary>
    10         /// iframe获取视图
    11         /// </summary>
    12         /// <returns></returns>
    13         public ActionResult GetView(string viewPara)
    14         {
    15             return View(viewPara);
    16         }
    复制代码

      在三个Action中分别设置断点,从登录页面跳转到主界面会发现,Index和Home执行到了,但是正常应该是执行Index和GetView,因为我们没有写任何关于Home链接的代码,如果我们直接进入的是主界面,会发现Index和GetView是执行到的,从上面可能明白一些,但是又好像不明白,这个有待研究。

      除了主界面加载的时候home链接问题,还有就是菜单点击iframe问题,解决方法就是每个页面写一个Action。

    EasyUI中DataGrid绑定

      easyui中使用datagrid绑定数据大家做的时候可能也用到过,主要是按照一定的json格式输出就行了,这是我第一次做,遇到下面问题,花了很多时间:

    复制代码
     1         /// <summary>
     2         /// 获取用户的所有信息
     3         /// </summary>
     4         /// <returns></returns>
     5         public ActionResult GetAllUserInfo()
     6         {
     7             int pageIndex = Request["page"] == null ? 1 : int.Parse(Request["page"]);
     8             int pageSize = Request["rows"] == null ? 20 : int.Parse(Request["rows"]);
     9 
    10             using (EasyUIDemoDBEntities db = new EasyUIDemoDBEntities())
    11             {
    12                 var data = from u in db.UserInfo
    13                            select new { u.ID, u.Name, u.Phone, u.Password, u.Mail, u.CreateTime, u.Address, u.Enable };
    14                 var result = new { total = data.Count(), rows = data };
    15                 return Json(result, JsonRequestBehavior.AllowGet);
    16             }
    17             return Json(datajson);
    18         }
    复制代码

      前端代码:

    复制代码
     1         $(function () {
     2             //初始化弹出窗体
     3             initTable();
     4         });
     5 
     6         //初始化表格 
     7         function initTable() {
     8             $('#test').datagrid({
     9                 title: '用户列表',
    10                 iconCls: 'icon-user',
    11                 loadMsg: '数据加载中...',
    12                 nowrap: true,
    13                 autoRowHeight: true,
    14                 striped: true,
    15                 url: '/User/GetAllUserInfo',
    16                 sortName: 'ID',
    17                 sortOrder: 'asc',
    18                 border: true,
    19                 remoteSort: false,
    20                 idField: 'ID',
    21                 pageSize:10,
    22                 pagination: true,
    23                 rownumbers: true,
    24                 columns: [[
    25                     { field: 'ck', checkbox: true },
    26                     { field: 'ID', title: 'ID',  50, sortable: true },
    27                     { field: 'Name', title: '用户名',  100, sortable: true },
    28                     { field: 'Phone', title: "电话",  150, sortable: true },
    29                     { field: 'Password', title: "密码",  150, sortable: true },
    30                     { field: 'Mail', title: "EMail",  150, sortable: true },
    31                     {
    32                         field: 'CreateTime', title: "添加时间",  150, sortable: true,
    33                         formatter: function (value, row, index) {
    34                             //return (eval(value.replace(//Date((d+))//gi, "new Date($1)"))).pattern("yyyy-M-d h:m:s");
    35                         }
    36                     },
    37                     { field: 'Address', title: "地址",  250, sortable: true },
    38                     {
    39                         title: '是否启用', field: 'Enable',  80, formatter: function (val, rowdata, index) {
    40                             if (val) {
    41                                 return '<a class="grid_Enable" href="javascript:void(0)" >' + val + '</a>';
    42                             } else {
    43                                 return '<a class="grid_unEnable" href="javascript:void(0)" >' + val + '</a>';
    44                             }
    45                         }
    46                     }
    47                 ]],
    48                 onLoadSuccess: function () {
    49                     $(".grid_Enable").linkbutton({ text: '启用', plain: true, iconCls: 'icon-ok' });
    50                     $(".grid_unEnable").linkbutton({ text: '禁止', plain: true, iconCls: 'icon-stop' });
    51                 },
    52             });
    53         }
    复制代码

      前端代码没什么问题,大家使用easyui绑定数据也是这么使用的,但是如果按照上面的代码是显示不出数据,最后找到原因是var result格式问题,修改一下代码如下:

    复制代码
     1             using (EasyUIDemoDBEntities db = new EasyUIDemoDBEntities())
     2             {
     3                 var temp = from u in db.UserInfo select u;
     4                 total = temp.Count();
     5                 var users = temp.OrderByDescending(s => s.ID)
     6                      .Skip<UserInfo>((pageIndex - 1) * pageSize).Take<UserInfo>(pageSize);
     7                 List<UserInfo> list = new List<UserInfo>();
     8                 foreach (UserInfo item in users)
     9                 {
    10                     list.Add(item);
    11                 }
    12                 var data1 = new
    13                 {
    14                     total = total,
    15                     rows = list
    16                 };
    17                 return Json(data1);
    18             }
    复制代码

      或者是修改rows = users.ToList<UserInfo>();隐式类型转化成泛型,其实说到底就是自己知识的不足,关于隐式类型和泛型,以及Json()方法的使用,虽然找到问题及解决方式,但是深层次的原因还是不清楚,可以查询绑定的完整代码:

    复制代码
     1         /// <summary>
     2         /// 获取用户的所有信息
     3         /// </summary>
     4         /// <returns></returns>
     5         public ActionResult GetAllUserInfo()
     6         {
     7             int pageIndex = Request["page"] == null ? 1 : int.Parse(Request["page"]);
     8             int pageSize = Request["rows"] == null ? 10 : int.Parse(Request["rows"]);
     9             int total = 0;
    10             using (EasyUIDemoDBEntities db = new EasyUIDemoDBEntities())
    11             {
    12                 var temp = from u in db.UserInfo select u;
    13                 total = temp.Count();
    14                 var users = temp.OrderByDescending(s => s.ID)
    15                      .Skip<UserInfo>((pageIndex - 1) * pageSize).Take<UserInfo>(pageSize);
    16                 var data = new
    17                 {
    18                     total = total,
    19                     rows = users.ToList<UserInfo>()
    20                 };
    21                 return Json(data);
    22             }
    23         }
    复制代码

      效果:

    新增、修改和删除数据

      这个简单示例服务端就只有一个上下文,下面以新增为例,修改删除都是类似操作,下载来看可以看下完整代码,新增用户操作前端代码:

    复制代码
     1     @*添加用户弹窗*@
     2     <div id="AddUserDialog" class="easyui-dialog" style="360px;height:310px;padding:10px 20px"
     3             closed="true" resizable="true" modal="true" buttons="#dlg-buttons" align="center">
     4         <form id="ff" method="post" novalidate="novalidate">
     5             <table id="tblAdd">
     6                 <tr>
     7                     <td><label for="Name">用户名:</label></td>
     8                     <td><input class="easyui-validatebox" type="text" id="Name" name="Name" data-options="required:true,validType:'length[1,32]'" /></td>
     9                 </tr>
    10                 <tr>
    11                     <td><label for="Password">密码:</label></td>
    12                     <td><input class="easyui-validatebox" type="text" id="Password" name="Password"  data-options="required:true,validType:'length[1,32]'" /></td>
    13                 </tr>
    14                     <tr>
    15                     <td><label for="PasswordOK">确认密码:</label></td>
    16                     <td><input class="easyui-validatebox" type="text" id="PasswordOK" name="PasswordOK" data-options="required:true" validType="equalTo['Password']" invalidMessage="两次输入密码不匹配" /></td>
    17                 </tr>
    18                     <tr>
    19                     <td><label for="Phone">电话:</label></td>
    20                     <td><input class="easyui-numberbox" type="text" id="Phone" name="Phone" data-options="validType:'length[1,14]'" /></td>
    21                 </tr>
    22                 <tr>
    23                     <td><label for="Mail">邮箱:</label></td>  
    24                     <td><input class="easyui-validatebox" type="text" id="Mail" name="Mail" data-options="required:true,validType:'email'" /></td>
    25                 </tr>
    26                 <tr>
    27                     <td><label for="Address">地址:</label></td>
    28                     <td><textarea id="Address" name="Address" style="height:50px;"></textarea></td>
    29                 </tr>
    30                 <tr>
    31                     <td><label for="Enable">启用:</label></td>
    32                     <td><select id="Enable" name="Enable" class="easyui-combobox" panelHeight='auto'>
    33                             <option value="1">启用</option>
    34                             <option value="0">禁止</option>
    35                         </select>
    36                     </td>
    37                 </tr>
    38                 <tr>
    39                     <td colspan="2" style="text-align:center; padding-top:10px">
    40                         <a href="javascript:void(0)" class="easyui-linkbutton" id="btnAddUser" iconcls="icon-ok" >确定</a>
    41                         <a href="javascript:void(0)" class="easyui-linkbutton" iconcls="icon-cancel" onclick="javascript:$('#AddUserDialog').dialog('close')">关闭</a>
    42                     </td>
    43                 </tr>
    44             </table>
    45         </form>
    46     </div>
    复制代码

      js代码:

    复制代码
     1         //添加用户对话框
     2         function AddUserDialog() {
     3             $('#AddUserDialog').dialog('open').dialog('setTitle', '添加用户');
     4             ClearText();
     5         }
     6         //添加用户添加事件
     7         function BindAddUserClickEvent() {
     8             $("#btnAddUser").click(function () {
     9                 //验证所有的文本框是否通过用户的验证
    10                 var valid = $('#ff').form('validate');
    11                 if (valid == false) {
    12                     return false;
    13                 }
    14                 var CBEnable = true;
    15                 if ($("#Enable").combobox('getValue')=="0") {
    16                     CBEnable = false;
    17                 }
    18 
    19                 //创建传递的参数
    20                 var postdata = {
    21                     Name: $("#Name").val(),
    22                     Password: $("#Password").val(),
    23                     Mail: $("#Mail").val(),
    24                     Phone: $("#Phone").val(),
    25                     Address: $("#Address").val(),
    26                     Enable: CBEnable
    27                 };
    28 
    29                 //发送异步请求到后台保存用户数据
    30                 $.post("/User/AddUser", postdata, function (data) {
    31                     if (data == "OK") {
    32                         alert("添加成功");
    33                         $('#AddUserDialog').dialog('close');
    34                         $("#test").datagrid("reload");
    35                     }
    36                     else {
    37                         alert("添加失败,请您检查");
    38                     }
    39                 });
    40             });
    41         }
    复制代码

      控制器代码:

    复制代码
     1         /// <summary>
     2         /// 添加用户
     3         /// </summary>
     4         /// <param name="userinfo"></param>
     5         /// <returns></returns>
     6         public ActionResult AddUser(UserInfo userinfo)
     7         {
     8             userinfo.CreateTime = DateTime.Now;
     9             using (EasyUIDemoDBEntities db = new EasyUIDemoDBEntities())
    10             {
    11                 db.UserInfo.Add(userinfo);
    12                 db.SaveChanges();
    13             }
    14             return Content("OK");
    15         }
    复制代码

      可以看到前端的AddUserDialog是一个添加用户弹窗,这里面主要注意的是一些easyui控件的取值或赋值操作,比如combobox的取值为:("#Enable1").combobox('getValue');赋值为:('#Enable').combobox('setValue', '1');这些都是一些小操作,用的时间长慢慢就会了。可以看到easyui使用起来还是蛮方便的,可能js脚本需要写东西,但是页面布局就很简单。控制 器那边只有一个上下文操作,没有任何封装,对于像小菜一样的我们是个福利,毕竟路是一点一点走出来的。

    效果图、完整示例Demo下载

      完整示例Demo下载:http://pan.baidu.com/s/1i3kMyzV

    后记

      上面的示例Demo可能对很多人来说很简单,但是如果你自己一点一滴的去完成它,你会发现会有很多的东西要去学习,有时候会眼高手低的去做一些事情,但反过头来确实高看了自己。当然这个Demo还有很多问题要去完善,现在还在学习中,与你共勉。

      如果你觉得本篇文章对你有所帮助,请点击右下部“推荐”,^_^

      EasyUI参考示例教程:

  • 相关阅读:
    关于跳板机登陆服务器一系列操作命令
    Linux环境搭建docker-selenium来运行UI自动化
    linux环境升级python2.7到python最新版本
    守护进程的理解--性能
    macbook添加webdriver驱动注意事项
    windows压测机本地端口号配置
    jmeter的bean shell 如何写数据到文件中
    Jenkins Pipeline介绍
    Jenkins创建Maven Job
    配置 Maven 项目使用 Nexus 仓库
  • 原文地址:https://www.cnblogs.com/develop/p/3661911.html
Copyright © 2020-2023  润新知