小型网站编写经验总结、出现的问题及解决办法总汇

这是几个月前做的一个项目吧,一直没有时间把做的总结打成电子版的,现在把项目里的一些经验和问题解决办法写出来分享,给一些初做小型网站的同学,让他们能少走些弯路吧,毕竟各种问题查找也很费时,我这里给总结了。我也是初学者,只是多些经验,可能也有一些地方说的不对,希望大家指出。

用到的平台:VS2005(ASP.NET)SQL SERVER 2005

 

1 网站架构的一些经验

我做的项目是一个小系统,编码时间周期短。网站的后台代码是参照的三层架构搭的,因为网站比较小,没必要做的调用关系太复杂,就是两个Helper类做底层,一个Manager类做业务层,上面的页面做表示层。开始觉得没什么用处,后来发现好处是真的有的。

首先,出了什么错,各页面都只要去Manager类里找就行了。其次,如果后来数据库什么的有大规模改动的时候只要在Manager类里批量改就可以,省了很多时间。而且,层次分明,函数复用什么的也都方便。

还有一点很重要的,数据库一定要在写代码前就设计好。做这个项目时就是因为没走这个流程,于是乎在我写完了Manager类后,开会讨论数据库大改,于是乎我在修改Manager类的时间那个花的太不值了。

关于网站的页面架构,由于之前有过调试DIV+CSS布局的各种串位还依然无解的经验,加之时间紧张,于是用的frameset分窗体,然后子窗体中用table来布局。

 

我编代码的顺序是:先写底层的两个Helper类,然后写页面文件,最后再按每个页面的调用关系等写各自的后台代码,后台代码中调用到的操作数据库的函数全写到Manager类中。写完后就是边测边完善了。

说点题外话,代码前一定要先设计好写成哪几个函数,一定要注意函数的复用,只是会复用的代码部分就尽量写成单个函数,此许不同的变量就换成函数参数的形式。我现在想起来接手一同学写的那一个文件里有2000行,大片大片重复代码,我还心惊肉跳的。那个文件里我最后改成可重用的部分只有300行,几乎是重写了。

 

2 底层Helper

在项目中涉及的内容不多,所以只写sqlHelperXMLHelper两个类。sqlHelper类建议可以上网下载一个前人写过的来进行参考,自己写的不一定比前人反复过的好。

 

1)复杂数据库SQL语句的编写

由于数据库需要可扩展,各种表分的很细,要查询的一条语句可能要综合几个表才能得出结果,之前的语句都自己手动编写,写完还要调看语句各种关系是否正确,很是头痛。后来一学长告知一个方法很好用:

VS05的任一页面上拖一个SqlDataSource,在配置数据源中选择“指定自定义SQL语句或存储过程”,然后就会有图形界面,选择你要综合的几个表及各字段关系等后,就可以自动生成所想要的SQL语句了,超方便!

 

2)页面防止SQL注入攻击

之前同学编写的时候全部用的是下面例子中的前一种方法,后来我去研究前人写的sqlHelper类时发现用的都是后一种方式,上网查得结果是可以防止页面上的SQL注入攻击,研究前人代码其实收获是很大的。防止SQL注入要使用参数化的SQL或存储过程,对密码等敏感信息要进行HASH,不要使用动态SQL语句,例如:

SQL注入的句子:string sqlstring = "SELECT * FROM usre WHERE name=’” + name +”’ and pw=’” + pw +”’";

SQL注入的句子:string sqlstring = "SELECT * FROM usre WHERE name=@name and pw=@pw";

SqlParameter name = new SqlParameter("@name", SqlDbType.Char, 10, name) };

SqlParameter pw = new SqlParameter("@pw", SqlDbType.Char, 10, pw) };

 

3XML的写入

这部分同学开始写时,是参照书上,书上用的是XmlTextWriter myXmlTextWritermyXmlTextWriter.WriteStartElement("Summary")myXmlTextWriter.WriteElementString("Version", "1.0")这两个主要函数来将内容写入XML文件,这几个函数有一点缺陷就是只能写一级节点,但是项目需要是要写入多级节点。可以使用下面类和函数:

XmlDataDocument xd = new XmlDataDocument();      //创建对象

xd.Load(new StringReader("<?xml version=/"1.0/" encoding=/"UTF-8/" ?>< Cmd></Cmd>"));

XmlElement cn1 = xd.CreateElement("Summary");

xd.DocumentElement.AppendChild(cn1);  //创建一级节点

 

XmlElement temp = xd.CreateElement(“Version”);

temp.InnerText = str2;    // Version节点的内容

cn1.AppendChild(temp);       //Summary下创建二级节点,三级节点的话再依次类推

xd.Save(“C://1.xml”);                    //最后SAVE对象到“C://1.xml”

还有一个是,为某一节点插入属性,例如< Summary Num=”2”>中的Num就是Count节点的一个属性。例如:

XmlAttribute ab_List = xd.CreateAttribute("Num");;

cn1.Attributes.Append(ab_List);

cn1.SetAttribute("Num", 2);

 

3 页面文件

当时设计页面的时候,讨论了很久,很多方案直到编码了还没定下来,那时候主要原因有个:一是技术上,有些控件不了解,一些可以用控件实现的功能没有想到,以至于不知道如何实现;二是在布局上有分歧,放一起觉得多了,分开就觉得版面有点太空了。对于第一点,就先做成一些固定的,把版面定下来,技术后来再学的,才解决。对于第二点,是做成可重用的,不同类型动态显示不同内容就好,一个页面就没那么拥挤了。这种解决也是没有办法的办法了,因为只有两个星期做,一个星期测,而且只有我一个人。

 

1)关于frameset分窗体后子窗体的跳转问题

第一次做服务器端,就是因为子窗体跳转问题找不到解决方案,于是放弃。这一次查到的可用的方法有两种:

一是使用JS脚本的方法

Response.Write("<script>window.parent.location=/"login.aspx/"</script>");     //使父窗体跳转至login.aspx页面

Response.Write("<script>window.parent.frames.item(2).location=/"main.aspx/"</script>");            //使frameset分窗体时的第3个子窗体跳转至main.aspx页面

二是使用超链接里的target属性实现

<a href="main.aspx" target="main" shape="rect">返回首页</a>       //使namemaintarget属性中)的子窗体跳转到main.aspx

我的方法可能不是什么正统方法,但这两种方法都能用。

 

2)网站登录页面控件Login使用

登录使用的是ASP.NET框架里自带的Login控件,使用

Login1.UserName//用户名

Login1.Password//密码

这两个来提取控件中用户输入的用户名和密码,(注意:这里所有的Login1都是该控件的ID号,如<asp:Login ID="Login1" runat="server"  ,当控件ID不同时,其对应也要修改)双击该控件即转到其对应事件函数,以下是一个示例代码:

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)

{

        //……

//在此之前需要自行编写数据库连接、验证过程

        //if (……)

        e.Authenticated = true;

//在代码中使用e(函数参数中的AuthenticateEventArgs e.Authenticated属性来告知Login控件验证通过

        //else

        //e.Authenticated = false;// 告知Login控件验证未通过

    }

Login控件通过验证后跳到指定的页面,此属性在属性中的DestinationPageUrl字段中修改。

 

3JS代码的调用问题

之前在页面上本来有很多效果想用JS做,但苦于写好了JS代码,在按钮事件里死活调用不了。后来看了很多帖子之后,估计这种情况是这个原因:ASP.NETButtonrunat=server”的,JS是客户代码,当点击Button时,自动提交到服务器,在其OnClick=””里写JS函数调用估计没用,不过看网上说OnClientClick事件是可以的,因为这个事件是在提交到服务器前触发的,但是在ASP.NETButton控件中没有这个事件。

还有在JS代码中,对ASP控件无法操作,原因可能也是因为是runat=server”。

另外,在C#代码中如果想调用JS代码,可以用下面的函数:

Page.ClientScript.RegisterStartupScript(Page.GetType(), "错误", "<script>alert('错误!');location='main.aspx'</script>");

 

4)网页中弹出新窗体(系统信息)问题

这个问题是在想做个弹出系统信息窗口时碰到的。

当时首先想到的就是像QQ空间一些应用要填信息时是让整个窗体变暗,中间一个窗口。查到这种实现的方法是在原来的窗体上再加一层DIV,覆盖整个窗体,但是由于要实现的功能也不需要获取输入法数据什么的,不需要这么复杂,就没用。当时查到有一个技术是叫“Lightbox JS”,有兴趣的可以去搜搜。

我使用的方法是一个弹出模态窗口,然后窗口中显示的是你自己事先写好的一个网页。

Page.ClientScript.RegisterStartupScript(Page.GetType(), "系统信息", "<script language='javascript' defer>window.showModalDialog( 'SystemInformation.aspx','系统信息','dialogLeft=400px;dialogTop=200px;dialogWidth=305px;dialogHeight=380px')</script>");

这里说说showModalDialog函数的几个参数:窗口用的页面文件名称,标题,窗口属性(距离窗口左、顶的距离,窗口的宽和高)。

 

5)页面实时刷新解决方案

由于直接刷新整个页面会闪屏,于是用了AJAXUpdatePanel控件,这个控件要使用要先下载安装AJAX工具包,这个安装过程就不说了,网上资料很多。当时没有找到UpdatePanel控件的触发更新的机制,我使用的这种方法可能会不对,但是算是实现功能了,因为没时间去深入学习AJAX了。方法如下:

在要局部刷新的页面中写入JS函数:id = setInterval("click()",3000);,即每隔3000毫秒执行一次click 函数,要停止则用window.clearInterval(id);语句。而function click(){ document.all.Button2.click(); } 即产生Button2按钮点击事件,则整个页面会提交,也就刷新了。要局部刷新只将Button2按钮放入UpdatePanel标签内的范围,例如:

<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

<ContentTemplate>

<asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_Click" style="display:none"/>

</ContentTemplate>

</asp:UpdatePanel>

 

6UpdatePanel无效果问题

在页面加入上面代码后,页面中却没有用,还是整个页面刷新,解决方法:

首先,将ScriptManager 标签放在form标签后,并设属性EnablePartialRendering="true"

然后在Web.config文件中的<system.web>  </system.web>标签中加入下面的代码:

<httpHandlers>

  <remove verb="*" path="*.asmx"/>

  <add verb="*" path="*.asmx" validate="false" type="Microsoft.Web.Script.Services.ScriptHandlerFactory, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

  <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

  <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

</httpHandlers>

 

4 后台代码

 

1IsPostBack属性

IsPostBackPage类的一个属性,一般出现在Page_Load函数中.当页面是第一次打开时,其值为False,若当前页面是一个提交后的页面,其值为True

也就是当你的页面第一次浏览时会调用if (Page.IsPostBack) {……}中的语句,而在此页面未被关闭之前再次进入该页面时,其中语句不会被调用。

而每次服务器端控件发生事件时,都会对Page类重构,调用Page_Load函数,然后才会调用事件响应函数。

 

2)页面传值

a)      可用Response.Redirect(aaa.aspx?Id= + Id);,但只能最长255字节,并且会在URL中显示。在跳转后的页面获取使用:Request.QuryString[Id]Request.Params[Id]

b)      不在URL中显示,可用Session,Cookie,Application

c)      最常用Post,利用Form提交。常用是把隐秘的数据存在隐藏域中由Form提交,适用大量数据,包括文件上传。在客户端form指定action目标后submit,在ASP. NET的伺服器中使用server.Transfer(url) 提交。用Request.Form[FormFieldID]获取。

d)      Cache,更新不及时,但大提高效率。

e)      ViewState,将页面各控件及其所有数据代存在name_ViewState的隐藏域中,存在HTML中,安全性低。

 

3)使用TABLE控件动态显示页面内容及样式控制

当时碰到的问题是要根据不同的传入值显示不同的tabletable的行列都不一样。开始想可能可以用JS来解决,但发现用table控件会更好,只要在页面中加入<asp:Table ID="Table1" runat="server"></asp:Table>控件,在后台代码中即可根据参数来对table控件进行控制。示例:

TableRow row1 = new TableRow();       //定义一个行对象

TableCell cell1 = new TableCell();        //定义一个单元格对象

cell1.Text = str;                               //给单元格cell1中的文本赋值

cell1.Font.Bold = true;                  //设定单元格cell1中的文字为粗体

cell1.ForeColor = Color.White;         //设定行对象cell1的前景色

row1.Cells.Add(cell1);                  //cell1加入到row1

row1.BackColor = Color.FromArgb(80, 124, 209); //设定行对象row1的背景色

Table1.Rows.Add(row1);                   //row1加入Table1到中

 

TABLE控件和GridView控件一样在属性中没法对其边框样式进行控制,这里可以用CSS。例如下面代码可以对cssclass=gridview的控件的每行的样式进行控制:

.gridview td {

      border-bottom: dotted 1px #333;

}

这里是对底部边框样式的设定。

 

4)正则表达式的使用

对于输入验证其合法性,加入命名空间“System.Text.RegularExpressions”,假设对IP地址进行验证,示例:

Regex rg = new Regex("^((2[0-4]//d|25[0-5]|1//d//d|[1-9]//d?|0)//.){3}(2[0-4]//d|25[0-5]| 1//d//d|[1-9]//d?|0)$");   //定义一个正则表达式对象

Match m = rg.Match(IP);       //IP为要验证的字符串

if (!m.Success)                    // m.Success如果为true表示验证通过

  return false;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值