net项目总结一(1)

中小型新闻发布系统

代码结构:分为实体层,数据层与接口,数据工厂层,业务逻辑层,公共层,UI层(由于图片上传实在麻烦,所以只上传少量而已),项目中用到了工厂模式,解耦BLL层和DLL层

1、登录功能,记住三天功能,basepage中统一验证

1、做验证码,利用自定义一般处理程序类来实现

2、利用cookie实现记住三天状态的功能,实现免登录功能(如果在公共环境不建议使用)

3、统一登录验证

4、实现统一错误页面处理 ,全局应用程序文件中的Application_Error()中实现

2、引入必要的js

3、

登陆页面中取消按钮的制作:

       <td>

<input type="button" value="登录" onclick="login()" />

<input type="button" value="取消" onclick="resetfm()" />

</td>

//4.0 负责清除当前表单中的所有带有name属性的控件值

function resetfm() {

document.getElementById("form1").reset();

}

4、建立验证码

4.1实现验证码逻辑:

/// <summary>

/// 实现验证码生成的一般处理程序类,记得在web.config中按照iis集成和经典模式做相应的配置

/// 由于此类中要使用session,所以必须实现接口IRequiresSessionState

/// </summary>

public class Vcode : IHttpHandler, System.Web.SessionState.IRequiresSessionState

{

public bool IsReusable

{

get { return false; }

}

public void ProcessRequest(HttpContext context)

{

//实现验证码功能

//1.0 产生验证码字符串

string vcode = GetVcode(4);

//2.0 将验证码字符串存入session

context.Session[Keys.Vcode] = vcode;

//3.0 将验证码字符串以图片的形式响应给浏览器

using (Image img = new Bitmap(65, 25))

{

//3.0.1 定义一个画家

using (Graphics g = Graphics.FromImage(img))

{

//3.0.2 利用画家对象在图片上将验证码字符串画上去

g.Clear(Color.White);

g.DrawRectangle(Pens.Red, 0, 0, img.Width - 1, img.Height - 1);

g.DrawString(vcode, new Font("黑体", 16, FontStyle.Bold | FontStyle.Strikeout), new SolidBrush(Color.Blue), 4, 4);

}

//3.0.3 利用图片的save方法将图片流保存到outputstream中

img.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);

}

}

Random r = new Random();

private string GetVcode(int num)

{

string[] arrcode = { "a", "b", "c", "d", "4", "2", "3" };

int arrLeng = arrcode.Length;

string res = string.Empty;

for (int i = 0; i < num; i++)

{

res += arrcode[r.Next(arrLeng)];

}

return res;

}

}

4.2写好了验证码的类,那么需要在配置文件中添加配置

<system.webServer>

<handlers>

<add  name="vcode" path="*.vcode" verb="*" type="EMS12.Site.admin.Vcode" />

</handlers>

</system.webServer>

4.3验证码调用示例

<td>

<input type="text" id="vcode" name="vcode" />

<img id="imgvcode" style="cursor: pointer" src="vcode.vcode" alt="验证码" height="25px" width="65px" />

</td>

4.4验证码点击替换(注意此时的math.random的用法)

//2.0 点击验证码图片的时候进行新的请求

$("#imgvcode").click(function () {

reflushvcode();

});

function reflushvcode() {

//this.src = "vcode.vcode?rid=" + Math.random(); //js的写法

$("#imgvcode").attr("src", "vcode.vcode?rid=" + Math.random()); //JQ的写法

}

5、利用ajax进行登陆验证。

5.1  //3.0 利用jquery ajax实现登录处理过程

function login() {

//1.0 获取表单form1中的所有带有name属性的参数的键值对

var parms = $("#form1").serialize();  //uname=?&pwd=?&vcode=?

//2.0 利用$.post方法将parms参数提交给 /actions/admin/login.ashx

$.post("/actions/admin/login.ashx", parms, function (ajaxobj) {

if (ajaxobj.status == "1") {

msgbox.showMsgErr(ajaxobj.msg, function () {

// 刷新页面

//window.location = window.location;

//刷新验证码

reflushvcode();

});

} else {

//登录成功

msgbox.showMsgOk(ajaxobj.msg, function () {

window.location = "index.aspx";

});

}

}, "json")

}

5.2接着开始撰写登陆验证一般处理程序(处理步骤是什么?)

using EMS12.BusinessLogicLayer;

using EMS12.Entity;

using EMS12.Common;//需要的是里面的key,一段加密验证

/// <summary>

/// login 的摘要说明

/// </summary>

public class login : BaseHandler, System.Web.SessionState.IRequiresSessionState  //继承两个接口,第二个接口来实现session

{

public override void SubPR()

{

Response.ContentType = "text/plain";

try

{

//开始登录逻辑编写

//1.0 接收参数

string uname = Request.Form["uname"];

string pwd = Request.Form["pwd"];

string vcode = Request.Form["vcode"];

//2.0 验证码的合法性验证

string vcodeFromSession = string.Empty;

if (Session[Keys.Vcode] != null)

{

vcodeFromSession = Session[Keys.Vcode].ToString();

}

if (string.IsNullOrEmpty(vcode)

|| vcode.Equals(vcodeFromSession, StringComparison.OrdinalIgnoreCase) == false)

{

WriteError("验证码错误");

// Response.End(); //此时会将当前处理现场强制终止,一定会抛出一个异常

return;

}

//3.0 验证用户名和密码的合法性

if (string.IsNullOrEmpty(uname) || string.IsNullOrEmpty(pwd))

{

WriteError("用户名或者密码不能为空");

return;

}

string md5pwd = Kits.MD5Entry(pwd);

UserInfoEntity entity = UserInfo_BLLSub.Login(uname, md5pwd);

if (entity == null)

{

WriteError("用户名或者密码错误");

return;

}

//4.0 将用户实体存入session[uinfo]

Session[Keys.uinfo] = entity;

//5.0 将ajaxobj对象序列化成json字符串返回

WriteSuncess("登录成功,正在跳转到首页....");

}

catch (Exception ex)

{

WriteError(ex.Message);

}

}

}

6.附加的kits。就是common下的加密验证

using System.Text.RegularExpressions;

/// <summary>

/// 帮助类

/// </summary>

public class Kits

{

/// <summary>

/// 判断当前字符串是否为一个数字

/// </summary>

/// <param name="str"></param>

/// <returns></returns>

public static bool IsInt(string str)

{

int res = 0;

return int.TryParse(str, out res);

}

/// <summary>

/// 判断当前字符串是否为一个数字

/// </summary>

/// <param name="str"></param>

/// <returns></returns>

public static bool IsNumber(string str)

{

//Regex reg = new Regex("^[0-9]+$");

Regex reg = new Regex("^\\d+$");

return reg.IsMatch(str);

}

/// <summary>

/// 将明文加密成md5格式的密文

/// </summary>

/// <param name="str"></param>

/// <returns></returns>

public static string MD5Entry(string str)

{

return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5");

}

/// <summary>

/// 负责将对象序列化成json字符串

/// </summary>

/// <param name="obj"></param>

/// <returns></returns>

public static string ToJsonString(object obj)

{

System.Web.Script.Serialization.JavaScriptSerializer jsor = new System.Web.Script.Serialization.JavaScriptSerializer();

return jsor.Serialize(obj);

}

/// <summary>

/// 负责将json字符串反序列化成对象

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="jsonstr"></param>

/// <returns></returns>

public static T DeserializeFromJsonString<T>(string jsonstr)

{

System.Web.Script.Serialization.JavaScriptSerializer jsor = new System.Web.Script.Serialization.JavaScriptSerializer();

return jsor.Deserialize<T>(jsonstr);

}

}

7.附加的BaseHandler,相当于父类

using EMS12.Common;

/// <summary>

/// 负责封装上下文中的相关属性

/// </summary>

public abstract class BaseHandler : IHttpHandler

{

#region 1.0 封装上下文中的相关属性

protected HttpContext Context

{

get

{

return HttpContext.Current;

}

}

protected HttpRequest Request

{

get

{

return this.Context.Request;

}

}

protected HttpResponse Response

{

get

{

return this.Context.Response;

}

}

protected HttpSessionState Session

{

get

{

return Context.Session;

}

}

#endregion

#region 2.0 封装ajax相关请求的方法和对象

AjaxObj obj = new AjaxObj();

/// <summary>

/// 成功返回统一调用

/// </summary>

/// <param name="msg"></param>

protected void WriteSuncess(string msg)

{

obj.status = Estatus.suncess;

obj.msg = msg;

Response.Write(Kits.ToJsonString(obj));

}

/// <summary>

/// 成功返回统一调用

/// </summary>

/// <param name="msg"></param>

/// <param name="data"></param>

protected void WriteSuncess(string msg, object data)

{

obj.status = Estatus.suncess;

obj.msg = msg;

obj.datas = data;

Response.Write(Kits.ToJsonString(obj));

}

/// <summary>

/// 统一进行错误异常信息的返回

/// </summary>

/// <param name="msg"></param>

protected void WriteError(string msg)

{

obj.status = Estatus.error;

obj.msg = msg;

Response.Write(Kits.ToJsonString(obj));

}

#endregion

public bool IsReusable

{

get { return false; }

}

public void ProcessRequest(HttpContext context)

{

// 什么都不做,只是调用一下子类中实现的抽象方法

SubPR();

}

public abstract void SubPR();

}

8.分析用户名和密码验证中,生成代码并没有那么应该怎么去做的逻辑。首先,我们想到去用new出BLL来。找到UserInfoBLLSub.cs,里面并没有提供任何函数,但是他继承于父类UserInfo_BLLSub : UserInfoBLLBase,在BusinessLogicLayerBase每个都有对应的父类。里面实现了全部的基本方法

看到方法:

/// <summary>

/// 得到 userinfo 数据实体

/// </summary>

/// <param name="user_id">user_id</param>

/// <returns>userinfo 数据实体</returns>

public static UserInfoEntity Get_UserInfoEntity(int user_id)

{

// Validate input

if(user_id<0)

return null;

// Use the dal to get a record

return _dal.Get_UserInfoEntity(user_id);

}

这里面只有通过id来获得实体而已。所以我们需要自己去写这个方法

步骤1:去接口层(IUserInfoDALSub.cs)定义一个接口:

那么我们先来看到接口层IUserInfoDALSub.cs

/// <summary>

/// 数据层 dbo.UserInfo 接口。

/// </summary>

public interface IUserInfoDataAccessLayer:IUserInfoDataAccessLayerBase

{

//发现还是继承了父类,接着我们去查看父类

}

父类:IUserInfoDAL(这个只是文件名,但是定义的接口名称是随意的,所以不要看错了

接口约定了我们基本的增删查改的方法

public interface IUserInfoDataAccessLayerBase

{

#region 基本方法

/// <summary>

/// 向数据库中插入一条新记录。

/// </summary>

/// <param name="_UserInfoModel">UserInfo实体</param>

/// <returns>新插入记录的编号</returns>

int Create_UserInfoInsert(UserInfoEntity _UserInfoModel);

/// <summary>

/// 向数据库中插入一条新记录。带事务

/// </summary>

/// <param name="sp">事务对象</param>

/// <param name="_UserInfoModel">UserInfo实体</param>

/// <returns>新插入记录的编号</returns>

int Create_UserInfoInsert(SqlTransaction sp,UserInfoEntity _UserInfoModel);

/// <summary>

/// 向数据表UserInfo更新一条记录。

/// </summary>

/// <param name="_UserInfoModel">_UserInfoModel</param>

/// <returns>影响的行数</returns>

int Create_UserInfoUpdate(UserInfoEntity _UserInfoModel);

/// <summary>

/// 向数据表UserInfo更新一条记录。带事务

/// </summary>

/// <param name="sp">事务对象</param>

/// <param name="_UserInfoModel">_UserInfoModel</param>

/// <returns>影响的行数</returns>

int Create_UserInfoUpdate(SqlTransaction sp,UserInfoEntity _UserInfoModel);

/// <summary>

/// 删除数据表UserInfo中的一条记录

/// </summary>

/// <param name="user_id">user_id</param>

/// <returns>影响的行数</returns>

int Create_UserInfoDelete(int user_id);

/// <summary>

/// 删除数据表UserInfo中的一条记录,带事务

/// </summary>

/// <param name="sp">事务对象</param>

/// <param name="user_id">user_id</param>

/// <returns>影响的行数</returns>

int Create_UserInfoDelete(SqlTransaction sp,int user_id);

/// <summary>

/// 根据UserInfo返回的查询DataRow创建一个UserInfoEntity对象

/// </summary>

/// <param name="row">row</param>

/// <returns>UserInfo对象</returns>

UserInfoEntity Populate_UserInfoEntity_FromDr(DataRow row);

/// <summary>

/// 得到 userinfo 数据实体

/// </summary>

/// <param name="user_id">user_id</param>

/// <returns>userinfo 数据实体</returns>

UserInfoEntity Get_UserInfoEntity(int user_id);

/// <summary>

/// 得到数据表UserInfo所有记录

/// </summary>

/// <returns>数据实体</returns>

IList< UserInfoEntity> Get_UserInfoAll();

/// <summary>

/// 检测是否存在根据主键

/// </summary>

/// <param name="user_id">user_id</param>

/// <returns>是/否</returns>

bool IsExistUserInfo(int user_id);

#endregion

}

于是,我们开始定义验证用户名和密码的接口:

/// <summary>

/// 数据层 dbo.UserInfo 接口。

/// </summary>

public interface IUserInfoDataAccessLayer:IUserInfoDataAccessLayerBase

{

UserInfoEntity GetUserInfo(string uname, string md5pwd);

}

步骤2:定义好接口之后,那么这个接口由谁去实现呢?其实,接口的父类,已经由DAL去实现了,可以查看UserInfoDAL.CS

我们查看的是EMS12.DataAccessLayer下的DataAccessLayer下的UserInfoDAL.CS,就是父类了

/// <summary>

/// 数据层实例化接口类 dbo.UserInfo.

/// </summary>

public partial class UserInfoDataAccessLayer : IUserInfoDataAccessLayer

{

里面实现了所有接口定义的方法

}

同时,我们要知道这里的DAL跟BLL不同,BLL中的之类是直接去继承父类的,   public class UserInfo_BLLSub : UserInfoBLLBase,

但是,DAL不是用之类去做的,而是用partial来形成共同代码,只是分开而已。public partial class UserInfoDataAccessLayer : IUserInfoDataAccessLayer,因为它是实现接口的。

于是我们在DAL中去实现这个接口:

/// <summary>

/// 数据层实例化接口类  dbo.UserInfo.

/// </summary>

public partial class UserInfoDataAccessLayer : IUserInfoDataAccessLayer

{

public UserInfoEntity GetUserInfo(string uname, string md5pwd)

{

UserInfoEntity _obj = null;

SqlParameter[] _param ={

new SqlParameter("@uname",SqlDbType.VarChar),

new SqlParameter("@md5pwd",SqlDbType.VarChar)

};

_param[0].Value = uname;

_param[1].Value = md5pwd;

string sqlStr = "select top 1 * from UserInfo where u_name [email protected] and u_pwd = @md5pwd ";

using (SqlDataReader dr = SqlHelper.ExecuteReader(Conn.SqlConn, CommandType.Text, sqlStr, _param))

{

while (dr.Read())

{

_obj = Populate_UserInfoEntity_FromDr(dr);

}

}

return _obj;

}

}

步骤3:那么DAL实现了之后呢,开始BLL的实现,那么要实现什么呢?

/// <summary>

/// 登录方法

/// </summary>

/// <param name="uname"></param>

/// <param name="md5pwd"></param>

/// <returns></returns>

public static UserInfoEntity Login(string uname, string md5pwd)

{

return _dal.GetUserInfo(uname, md5pwd);

}

#endregion

步骤4:开始校验

UserInfoEntity entity = UserInfo_BLLSub.Login(uname, md5pwd);

if (entity == null)

{

WriteError("用户名或者密码错误");

return;

}

步骤五:由于受到工厂模式的作用,反射等,所以全部归结到UI层中被调用

怎么限制到的呢?是在web.config配置的

<configuration>

<connectionStrings>

<add name="conn" connectionString="server=.;database=kyprint;uid=sa;pwd=master;"/>

</connectionStrings>

<appSettings>

<!--表示在工厂中要通过此配置获取DAL层程序集并且反射出其中的类的对象-->

<add key="Dal" value="EMS12.DataAccessLayer" />

</appSettings>

<system.web>

<compilation debug="true" targetFramework="4.5" />

<httpRuntime targetFramework="4.5" />

</system.web>

<system.webServer>

<handlers>

<add  name="vcode" path="*.vcode" verb="*" type="EMS12.Site.admin.Vcode" />

</handlers>

</system.webServer>

</configuration>

9、后台管理中心首页菜单的制作

<%=menus %>

直接用上定义好的字符串,再在后台处理这个字符串

/// <summary>

/// 负责存放从menus表中查询出数据以后动态拼装成li标签代码

/// </summary>

public System.Text.StringBuilder menus = new System.Text.StringBuilder(200);

protected void Page_Load(object sender, EventArgs e)

{

InitMenus();

}

private void InitMenus()

{

//1.0 查询数据表menus以集合的形式返回

IList<MenusEntity> list = Menus_BLLSub.Get_MenusAll();

//2.0 遍历 集合,生成1级菜单

if (list.Any())   //判断集合有没有数据的方法

{

foreach (MenusEntity item in list)

{

//判断当前数据是否是一级菜单并且状态为正常

if (item.m_parent_mid < 0 && item.m_status == (int)ENums.EState.Normal)

{

menus.AppendLine("<li class=\"level1\">" + item.m_name + "</li>");

//3.0 遍历 集合,生成2级菜单

GenSubMenus(item.m_id, list);

}

}

}

}

时间: 2024-08-29 16:33:18

net项目总结一(1)的相关文章

Win10下IIS配置、项目发布、添加网站

Win10下IIS配置 1.找到控制面板:[开始]菜单鼠标右击,打开[控制面板] 2.打开控制面板,点击[程序],点击[启用或关闭Windows功能] 下一步,点击[启用虎关闭Windows功能] 3. 开始修改IIS了,我是这样勾上的,有可能比较多. 4. 验证IIS是否正确安装,等待几分钟后IIS配置完成.在浏览器输入http://localhost/iisstart.htm会出现 IIS安装成功页面.第一次修改的时候出现了成功页面,但是后来删除了IIS中默认的网站就打不开了,但是不影响的.

使用 IDEA 创建 Maven Web 项目 (异常)- Disconnected from the target VM, address: &#39;127.0.0.1:59770&#39;, transport: &#39;socket&#39;

运行环境: JDK 版本:1.8 Maven 版本:apache-maven-3.3.3 IDEA 版本:14 maven-jetty-plugin 配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${pro

MyEclipse建立SpringMVC入门HelloWorld项目

一.首先,建立空的web project项目: 1. 2. 3. 二.其次,导入先关jar包 1.将jar包导入SpringMVCHelloWorld\WebRoot\WEB-INF\lib目录下 三.接下来修改web.xml文件,在web中,指定我们的DispatcherServlet.(从这里进入SpringMVC的可控范围). 1. 2.web.xml中的内容如下: <?xml version="1.0" encoding="UTF-8"?> &l

如何用 Android Studio 导入开源项目以及常见错误的解决办法

声明:这篇文章完全来自这篇文章,感谢大神的相助.这篇文章纯粹是为了备份. 本篇以Github上最热门的MaterialDesign库,MaterialDesignLibrary来介绍怎样使用Android Sudio导入开源项目的,如果你和我一样刚刚从Eclipse转到AS,那本篇文章非常适合你. 如果不引入任何第三方库,不做自动化分渠道打包等操作,那可以在完全不了解Gradle的情况下进行Android项目的开发.但如果要想导入Github上的热门项目,必须首先熟悉Gradle. 1. Gra

【机器学习实战】Machine Learning in Action 代码 视频 项目案例

MachineLearning 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远 Machine Learning in Action (机器学习实战) | ApacheCN(apache中文网) 视频每周更新:如果你觉得有价值,请帮忙点 Star[后续组织学习活动:sklearn + tensorflow] ApacheCN - 学习机器学习群[629470233] 第一部分 分类 1.) 机器学习基础 2.) k-近邻算法 3.) 决策树 4.) 基于概率论的分类方法:朴素

git 把本地创建的项目放到github上

很早之前就注册了Github,但对其使用一直懵懵懂懂,很不熟练.直到昨天做完百度前端技术学院的task,想把代码托管到Github上的时候发现自己对于Git的操作是如此之愚钝,所以今天决定把Git好好学习一遍,好让自己以后能更好地使用Github,主要还是通过Git教程 - 廖雪峰的官方网站来学习.简要步骤可以直接看最后的总结. Git的安装就不说了. 第一步:我们需要先创建一个本地的版本库(其实也就是一个文件夹). 你可以直接右击新建文件夹,也可以右击打开Git bash命令行窗口通过命令来创

eclipse部署tomcat修改项目访问路径(虚拟路径)

原文参考: http://www.educity.cn/wenda/147993.html http://blog.163.com/java_zf/blog/static/19926038420129240314546/ tomcat部署web项目(eclipse自动部署项目到tomcat,访问URL中不包含部署名) 最近项目中需要把项目部署到tomcat中,并且访问路径中不包含不署名,且想实现Eclipse中的自动部署,扒了好久资料,最终实现了自己的需求,呵呵,如下: 1. 把项目contex

配置resin web方式部署项目

写在前面,推荐下载resin4.0.47版本.其它版本没有测试 最近打算做一个小项目,然后容器选用了resin.想通过web提交war文件的方式 进行部署,更新代码也方便. 试了resin最新的版本(目前最新版本为4.0.53),提交war文件到webapps下面都是.tmp文件.百度google一通还是没找到解决办法. 看了下公司用的resin版本,选择4.0.47.下载后发现没最新版本的上传问题. 通过web提交war文件方式步骤如下: 步骤一:修改resin.properties.推荐配置

jsp获取当前项目跟路径

在jsp中获取当前项目的根路径: <% String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";%> 可以使用${basePath}获取.

eclipse 创建maven web项目

前言: 前面那一篇讲解了Maven的作用以及详细的应用,不了解Maven的具体使用,请参读:http://www.cnblogs.com/hongwz/p/5456578.html,下面来说明一下IDE构建Maven项目. 1.新建Maven项目 1.1 File -> New -> Other 1.2 选择Maven Project ,单击Next 1.3 保持默认即可,单击Next 1.4 选择Archetype为 web app,单击Next 1.5 输入一些必要信息,单击Finish