不拖控件ASP.NET——NVelocity(2)

    上节课我们讲述了NVelocity的简单应用,但是没有和数据库打交道,这次我们来和数据库连接实现人员的增删改查。

1.      上篇博客回顾

    链接:http://blog.csdn.net/u010955843/article/details/42528761

    开讲之前,我们先来回顾上一节课讲的内容,主要是两个页面,一个是一般处理程序的页面,另一个是渲染后的模板。

?  机制

    上篇博客中我们建立一个person类,并且在一般处理程序中对其进行了赋值,之后交给了模板(html)进行数据填充,渲染成html页,之后生成的纯html文本返回给一般处理程序将,一般处理程序将其返回给浏览器进行解析,并且显示。

?  好处

    实现了数据和逻辑和界面的分离:数据给了模板(一般由html担当),最后一般处理程序拿到渲染html进行输出;模板不管数据来源,只是知道表格中需要设置几行几列;一般处理程序只是取数据,传给模板,不管模板会把数据渲染成什么样子的,也就是各自只是负责自己的那一块就可以了

2.      与数据库连接实现人员增删改查

    上节课我们只是在一般处理程序中写的数据源对象,那么在传统web开发NVelocity如何数据库进行交互的呢,我们先来介绍程序编写的步骤。

?  建立数据库并且建表

     可以自己定,我们的库为CRUDTest,表明为Persons

    设置Id为自增的,我们可以手动输入几条记录

?  CommonHelper

    和上次一样,我们首先下载NVelocity的DLL,之后将其添加到建立的相应项目下,直接拖进项目下面即可,之后添加对它的引用即可。

    上次我们是将模板写在一个一般处理程序中,但是我们知道这样的只是适用一个或者少数的处理程序,要是想要达到模板的复用或者方便的使用,我们可以将其进行封装,放到一个类中即可,这样实现了方法的复用。

    我们知道这里只是有两个参数不一样,即将渲染的模板,另一个是将要填充模板的文件或者数据。

    具体代码如下:

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using NVelocity;
using NVelocity.App;
using NVelocity.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

//using NVelocity;using NVelocity.App;using NVelocity.Runtime;必须引入的
//这个类用于封装Nvelocity模板的渲染
namespace yinqingmuban
{
    public class commonHelper
    {
        /// <summary>
        /// 用data数据填充templateName模板,渲染生成html返回
        /// </summary>
        /// <param name="templateName">模板名字</param>
        /// <param name="data">填充模板数据</param>
        /// <returns></returns>
        public static string RenderHtml(string templateName, object data)
        {
            VelocityEngine vltEngine = new VelocityEngine();
            vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");
            vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹,我们遵从上次讲的我们还是放在templates这个文件夹中,自己也可以新建别的名字的
            vltEngine.Init(); //引擎初始化

            VelocityContext vltContext = new VelocityContext();
            vltContext.Put("Data", data);//设置参数,在模板中可以通过$data来引用

            Template vltTemplate = vltEngine.GetTemplate(templateName);//渲染的html模板
            System.IO.StringWriter vltWriter = new System.IO.StringWriter();
            vltTemplate.Merge(vltContext, vltWriter);

            string html = vltWriter.GetStringBuilder().ToString();
            return html;
        }
    }
}</span></strong>

?  Sqlhelper

    相信大家都学过三层,这里不再做过多的介绍。封装了一系列的增删改查的方法,并且建立了数据库的里连接。这里不再展示了

?  配置文件

    用于配置连接数据库的字符串,这样便于我们灵活更换数据库,而不用于更改代码内部。

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><connectionStrings>
  <add name="conStr" connectionString="data source=.;database=CRUDTest;uid=sa;pwd=123456;"/>
</connectionStrings></span></strong>

?  人员显示的一般处理程序(personlist.ashx)

这里主要是读取数据,然后把它渲染到html页上进行输出。

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;

namespace yinqingmuban
{
    /// <summary>
    /// personlist 的摘要说明
    /// </summary>
    public class personlist : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";
            //context.Response.Write("Hello World");
            DataTable dt = sqlHelper.ExecuteDataTable("select * from Persons");
            //DataTable不是集合,所以无法foreach遍历,DataTable的Rows属性
            //代表表格中的数据行的集合(DataRow的集合),一般传递DataRowCollection
            //给模板方便遍历
            string html = commonHelper.RenderHtml("personlist.html", dt.Rows);

            context.Response.Write(html);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong>

?  建立人员列表的渲染模板(personlist.html)

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <!-- 人员的操作处理,增删改查 -->
    <a href="personEdit.ashx?Action=AddNew">新增人员</a>
    <!--//变量data中的每一行,并且输入每一行中的每一列的字段值-->
    <table>
        <thead>
            <tr><td>删除</td><td>编辑</td><td>姓名</td><td>年龄</td><td>邮箱</td></tr>
        </thead>
        <tbody>
            #foreach($person in $Data)
            <tr><td><a href="personEdit.ashx?Action=Delete&Id=$person.Id">删除</a></td><td><a href="personEdit.ashx?Action=Edit&Id=$person.Id">编辑</a></td><td>$person.Name</td><td>$person.Age</td><td>$person.Email</td></tr>
            #end
        </tbody>
    </table>
</body>
</html>
</span></strong>

?  对列表进行增删改(personEdit.ashx)

<strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data;
namespace yinqingmuban
{
    /// <summary>
    /// personEdit 的摘要说明
    /// </summary>
    public class personEdit : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";
            //PersonEdit.ashx?action=AddNew
            //PersonEdit.ashx?action=Edit&Id=3
            string action = context.Request["action"];
            if (action == "AddNew")
            {
                //判断是否含有Save并且等于true,如果是的话就说明是点击【保存】按钮请求来的
                bool save = Convert.ToBoolean(context.Request["Save"]);
                if (save)//是保存
                {
                    string name = context.Request["Name"];
                    int age = Convert.ToInt32(context.Request["Age"]);
                    string email = context.Request["Email"];

                    sqlHelper.ExecuteNonQuery("Insert into Persons(Name,Age,Email) values(@Name,@Age,@Email)", new SqlParameter("@Name", name)
                        , new SqlParameter("@Age", age)
                        , new SqlParameter("@Email", email));
                    context.Response.Redirect("personlist.ashx");//保存成功返回列表页面
                }
                else
                {
                    //string html = CommonHelper.RenderHtml("PersonEdit.htm", new { Name = "", Age = 20, Email = "@rupeng.com" });
                    //定义匿名对象  Action可能与数据库中字段重复,建议分开,相关和无关的字段;New一个匿名类型,等于在一个匿名类中又创建一个匿名类,
                    var data = new { Action = "AddNew", Person = new { Name = "", Age = 20, Email = "@rupeng.com" } };
                    //进行渲染
                    string html = commonHelper.RenderHtml("personEdit.html", data);
                    context.Response.Write(html);
                }
            }
            else if (action == "Edit")
            {
                //判断是否含有Save并且等于True,如果是的话说明点击了保存按钮
                bool save = Convert.ToBoolean(context.Request["Save"]);
                if (save)
                {
                    //所有的信息服务器端尽量不要记,尽量通过客户端传递
                    //服务器是一个健忘症(无状态),服务器只认识Request中的信息
                    long id = Convert.ToInt64(context.Request["Id"]);
                    string name = context.Request["Name"];
                    int age = Convert.ToInt32(context.Request["Age"]);
                    string email = context.Request["Email"];
                    sqlHelper.ExecuteNonQuery("update Persons set [email protected],[email protected],[email protected] where [email protected]", new SqlParameter("@Id", id), new SqlParameter("@Name", name), new SqlParameter("@Age", age), new SqlParameter("@Email", email));
                    context.Response.Redirect("personlist.ashx");
                }
                else
                {
                    long id = Convert.ToInt64(context.Request["Id"]);
                    DataTable dt = sqlHelper.ExecuteDataTable("select * from Persons where [email protected]", new SqlParameter("@Id", id));
                    if (dt.Rows.Count <= 0)
                    {
                        context.Response.Write("没有找到Id=" + id + "的数据");
                    }
                    else if (dt.Rows.Count > 1)
                    {
                        context.Response.Write("找到多条Id=" + id + "的数据");
                    }
                    else
                    {
                        DataRow row = dt.Rows[0];
                        var data = new { Action = "Edit", Person = row };
                        string html = commonHelper.RenderHtml("personEdit.html", data);
                        context.Response.Write(html);
                    }
                }  

            }
            else if (action == "Delete")
            {
                long id = Convert.ToInt64(context.Request["Id"]);
                sqlHelper.ExecuteNonQuery("delete from Persons where [email protected]", new SqlParameter("@Id",id));
                context.Response.Redirect("personlist.ashx");
             }
            else
            {
                context.Response.Write("Action参数错误!");
            }  

            }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong>

?  建立人员增删改的渲染模板(personEdit.html)

<strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>
        #if($Data.Action=="AddNew")
        新增用户
        #else
        编辑用户$Data.Person.Name
        #end
    </title>

</head>
<body>
    <form action="personEdit.ashx" method="post">
        <!--<input type="hidden" name="Action" value="AddNew" />-->
        <input type="hidden" name="Action" value="$Data.Action" />
        <input type="hidden" name="Save" value="true" />
        #if($Data.Action=="Edit")
        <input type="hidden" name="Id" value="$Data.Person.Id" />
        #end

        <table style="background-color:blueviolet">
            <tr><td>姓名:</td><td><input type="text" name="Name" value="$Data.Person.Name" /></td></tr>
            <tr><td>年龄:</td><td><input type="text" name="Age" value="$Data.Person.Age" /></td></tr>
            <tr><td>邮箱:</td><td><input type="text" name="Email" value="$Data.Person.Email" /></td></tr>
            <tr><td></td><td><input type="submit" value="保存" /></td></tr>
        </table>
    </form>
</body>
</html>
</span></strong>

?  效果

   
列表显示

   
点击新增人员

    点击编辑

    通过隐藏字段来实现想要的结果,在实现增删改的页面我们用了隐藏字段,隐藏字段是服务器端控件,这样我们在服务器端可以通过隐藏字段的name来获得其相应的值,主要是因为关于一些操作这些是不要用户可以看到的,只是程序需要看到,故而做成了隐藏字段。

    至此我们就实现与数据库的交互,出现的效果自己可以写写代码看一下啊。

3.      总结

    这样总算完美了,不然总是觉得少了些什么,自己最近时间紧,一直没有写这篇与数据库交互的博客,在mvc中同样存在一个引擎Razor,我们称之为视图引擎,希望在这篇博客的基础能够激起你对引擎探究的好奇心,自己去看看和研究吧,相信你会感兴趣的。

时间: 2024-10-05 16:39:35

不拖控件ASP.NET——NVelocity(2)的相关文章

不拖控件ASP.NET——NVelocity(1)

    模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档.今天我们主要来介绍NVelocity模板引擎 1. NVelocity基础 ?  定义     NVelocity是一个基于.NET的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象.从而使得界面设计人员与.NET程序开发人员

不拖控件ASP.NET——一般处理程序

    习惯了微软提供的一系列Web控件,用着很方便,最近看了一种新的方式不用拖控件就能实现同样的功能,究竟拖控件好还是不拖控件好,随着以后学习的深入,答案会慢慢揭晓,希望一直关注哦!今天我们来看看一般处理程序. 1.      一般处理程序(HttpHandler) ?  引入     我们从一个网站打开的流程讲起.如下图:     流程细说:用webForm开发一个模拟的登陆页面,用户打开登陆页面,填入相应的用户信息:用户名和密码,点击[登陆]按钮,浏览器将用户名和密码发送给网站服务器,网站

不拖控件ASP.NET——探知cookie和session(2)

    接着上篇的博客我们来讲解服务器端保存数据的机制-session     我们知道cookie是保存在客户端的,这样数据就存在一个不安全性,此外还有 一个问题就是不能够存储大量的数据,我们上篇博客还遗留一个问题就是客户端是可以篡改数据的,相当于保留在病人手上的病历本是可能被用户篡改的(一般情况下,用户不会篡改,这样多危险了,医生误诊怎么办?哈哈)     此外医生会给每个患者编制一个编号,并且自己再保存一个编号,这样当病人来的时候根据编号来识别病人的身份,当然用户会可以别人的编号猜出来自己

不拖控件ASP.NET—探知cookie和session(1)

1.      为什么会出现cookie和session? ?  先看一个例子:     我们还是使用之前的NVelocity,不清楚的参看链接:http://blog.csdn.net/u010955843/article/details/42977533,同样建立commonhelper类,里面封装NVelocity模板,并且建立html也作为渲染的模板进行显示.      html页 <span style="font-family:Microsoft YaHei;">

不拖控件的asp.net编程方法——第1回

以前写的asp.net程序基本上都用了webfrom的控件编写的,当然有个好处就是易入门.快速效率高,但感觉自己这了几个小系统,还是没学到什么东西,感觉心里没底,因为都是封装好的东西,拿来就用的,功能能实现,但原理性的东西不明白,所以遇到有些错误根本无从下手,虽然貌似很多公司开发都有控件,但作为学生个人觉得还是别用好,当然那些自定义控件的又另当别论. 本想深入研究asp.net MVC,但发现不懂的知识太多了,所以现在暂时先学HTML+ashx这样的形式,换成这种形式写还真不习惯,下面把我今天学

【Visual Basic】纯代码不拖控件,利用动态生成控件的方式完成一个简单的四则运算计算器

vb6是一个典型的拖控件加代码的编程代表,因此也一直被认为难登大雅之堂,但是,在vb6中可以完全纯粹地使用代码控制这个窗体与窗体的控件.这样生成出来的控件位置摆放精确无比,无须拖好控件之后,再利用工具栏的"格式"菜单慢慢地调整大小.这种方式的确定是声明一个控件要耗费大量的代码,但其实Java中的Swing,HTML+CSS排放控件,比这好不了多少. 当然,比vc6中mfc的代码简单了不少,具体见<[mfc]基本对话框程序--加法器>(点击打开链接) 一.基本目标 利用纯粹代

ASP.NET控件&lt;ASP:Button /&gt; html控件&lt;input type=&quot;button&quot;&gt;区别联系

ASP.NET控件<ASP:Button />-------html控件<input type="button">杨中科是这么说的:asp和input是一样的东西 服务器只认识input,我们可以直接写input 但是asp是要把自己自动翻译成input再交给服务器的.其实是一样的东西 写写我看到的区别:                asp控件,直接可以用c#编程                input加上 runat=“server” 也被c#编程了 说白

【实战项目】【FLEX】#900 实现拖控件功能

一.功能说明:拖控件的功能(类似FLEX,VS 里面的拖控件). 提示:大家对事件的注册和派发的说法可能不一样.因为在FLEX中和在Java中,叫法有的区别.但是本质是一样的. 注册事件  == 设置监听事件    ||       派发事件 == 触发事件  ,也有人叫 “进行广播”            大家知道什么意思就好.   说明: 1.Application页面(放置控件列表,页面容器,属性面板这三个模块的Application页面)[PS:以下简称:主页面 ] 1.1  主页面加载

文件上传控件asp:FileUpload

前端 使用的控件<asp:FileUpload ID="fileup" runat="server" /><span class="message">*</span> $("#btn_Save_").click(function () { var url = "Upload.aspx?_method=import";// url += "&_method