一步一步asp.net_三层构架总结

上次简单的总结了三层构架,这次,总结关于项目架构方面的东西,哈!

第一个,当然是文件管理..

一个项目一个完整的目录结构,是一个很好的方式,就像asp.net MVC充满了美感.....

image

MVC项目的整体结构非常清晰,我们就要借鉴这种方式,

从建立文件开始,规范,

imageimage

可以看到,目录清晰,非常容易对各个模块进行管理,也非常适合了解整个网站架构

整个网站目录架构是一个网站的细节,越清晰越容易后期维护和开发.

在这里面涉及到几个很重要的地方:

1.系统日志管理和系统日志

2.文件存取管理

3.系统配置管理

可以说,这三个模块什么网站都可以加进去,这三个模块,具体干什么的呢?

系统日志管理.

主要是记录系统的程序运行异常信息(Log4net框架),还有一个就是系统操作的日志

系统异常日志,方便程序员调试,而且记录系统所有的异常.

image

系统操作的日志,管理员登录后台以后,做的所有操作都记录下来(这个大家都懂的....哈哈....)

image

文件存取管理

很多数时候,我们数据库存取图片,保存图片路径(使用相对路径的方式),然后,本地这么调用

image

但是,这种方式,简直就是坑爹,如果xxx让你现在我们图片要迁移到专门的服务器,...............

可以想象.....工作量+∞..................

因此,我们可以考虑一个折中的方式,比如,专门一个模块负责帮你读取你需要的图片和上传图片,你只需要告诉它,需要什么类型的图片,什么大小,什么尺寸,

就是这样子

   1:  <%@ WebHandler Language="C#" Class="GetFile" %>
   2:   
   3:  using System;
   4:  using System.Web;
   5:  using Common;
   6:  using System.IO;
   7:  public class GetFile : IHttpHandler {
   8:      public static string ServerPic="../Pictures/";
   9:      public void ProcessRequest(HttpContext context)
  10:      {
  11:   
  12:          String methodName = context.Request["method"];
  13:          if (!string.IsNullOrEmpty(methodName))
  14:              CallMethod(methodName, context);
  15:      }
  16:      /// <summary>
  17:      /// 根据业务需求调用不同的方法
  18:      /// </summary>
  19:      /// <param name="Method">方法</param>
  20:      /// <param name="context">上下文</param>
  21:      public void CallMethod(string Method, HttpContext context)
  22:      {
  23:          switch (Method)
  24:          {
  25:   
  26:              case "GetMasterPic":
  27:                  GetMasterPic(context);
  28:                  break;
  29:              case "GetMasterCert":
  30:                  GetMasterCert(context);
  31:                  break;
  32:              case "GetCompanyPic":
  33:                  GetCompanyPic(context);
  34:                  break;
  35:              case "GetLogoCompanyPic":
  36:                  GetLogoCompanyPic(context);
  37:                  break;
  38:              case "GetMainProductPic":
  39:                  GetMainProductPic(context);
  40:                  break;
  41:              case "GetOtherProductPic":
  42:                  GetOtherProductPic(context);
  43:                  break;
  44:              default:
  45:                  return;
  46:   
  47:   
  48:          }
  49:      }
  50:      /// <summary>
  51:      /// 获得大师的荣誉信息图片
  52:      /// </summary>
  53:      /// <param name="context"></param>
  54:      public void GetMasterCert(HttpContext context)
  55:      {
  56:          string type = context.Request["type"];//要访问的图片尺寸
  57:          string fileName = context.Request["fileName"];//文件名称
  58:   
  59:          string VirtualPath = ServerPic + "Master/MasterCert/";//文件虚拟路径
  60:   
  61:          if (!Tools.IsValidInput(ref fileName, true))
  62:          {
  63:              return;
  64:          }
  65:          //真实路径
  66:          string PicTypeDirectory = GetPicType(type);
  67:          if (PicTypeDirectory != null)
  68:              VirtualPath += GetPicType(type);
  69:          else
  70:              VirtualPath += ServerPic + "NoPic.jpg";
  71:          
  72:          WriteImg(context, VirtualPath + fileName);//输出图片
  73:      }
  74:      /// <summary>
  75:      /// 获取产品其他图片
  76:      /// </summary>
  77:      /// <param name="context"></param>
  78:      public void GetOtherProductPic(HttpContext context)
  79:      {
  80:          string type = context.Request["type"];//要访问的图片尺寸
  81:          string fileName = context.Request["fileName"];//文件名称
  82:   
  83:          string VirtualPath = ServerPic + "Product/OtherProductPic/";//文件虚拟路径
  84:   
  85:          if (!Tools.IsValidInput(ref fileName, true))
  86:          {
  87:              return;
  88:          }
  89:          //真实路径
  90:          string PicTypeDirectory = GetPicType(type);
  91:          if (PicTypeDirectory != null)
  92:              VirtualPath += GetPicType(type);
  93:          else
  94:              VirtualPath += ServerPic + "NoPic.jpg";
  95:   
  96:          WriteImg(context, VirtualPath + fileName);//输出图片
  97:      }
  98:      /// <summary>
  99:      /// 获得产品的图片
 100:      /// </summary>
 101:      /// <param name="context"></param>
 102:      public void GetMainProductPic(HttpContext context)
 103:      {
 104:          string type = context.Request["type"];//要访问的图片尺寸
 105:          string fileName = context.Request["fileName"];//文件名称
 106:          
 107:          string VirtualPath = ServerPic+"Product/MainProductPic/";//文件虚拟路径
 108:          
 109:          if (!Tools.IsValidInput(ref fileName, true))
 110:          {
 111:              return;
 112:          }
 113:          //真实路径
 114:          string PicTypeDirectory = GetPicType(type);
 115:          if (PicTypeDirectory != null)
 116:              VirtualPath += GetPicType(type);
 117:          else
 118:              VirtualPath += ServerPic + "NoPic.jpg";
 119:          
 120:          WriteImg(context,VirtualPath + fileName);//输出图片
 121:      }
 122:      /// <summary>
 123:      /// 获得大师的图片
 124:      /// </summary>
 125:      /// <param name="context"></param>
 126:      public void GetMasterPic(HttpContext context)
 127:      {
 128:          string type = context.Request["type"];//要访问的图片尺寸
 129:          string fileName = context.Request["fileName"];//文件名称
 130:   
 131:          string VirtualPath =  ServerPic+"Master/MainMasterPic/";//文件虚拟路径
 132:          if (!Tools.IsValidInput(ref fileName, true))
 133:          {
 134:              return;
 135:          }
 136:          //真实路径
 137:          string PicTypeDirectory = GetPicType(type);
 138:          if (PicTypeDirectory != null)
 139:              VirtualPath += GetPicType(type);
 140:          else
 141:              VirtualPath += ServerPic + "NoPic.jpg";
 142:          
 143:          WriteImg(context, VirtualPath + fileName);//输出图片
 144:      }
 145:      /// <summary>
 146:      /// 获得企业美景图
 147:      /// </summary>
 148:      /// <param name="context"></param>
 149:      public void GetLogoCompanyPic(HttpContext context)
 150:      {
 151:          string type = context.Request["type"];//要访问的图片尺寸
 152:          string fileName = context.Request["fileName"];//文件名称
 153:   
 154:          string VirtualPath = ServerPic + "Company/CompanyPic/";//文件虚拟路径
 155:          if (!Tools.IsValidInput(ref fileName, true))
 156:          {
 157:              return;
 158:          }
 159:          //真实路径
 160:          string PicTypeDirectory = GetPicType(type);
 161:          if (PicTypeDirectory != null)
 162:              VirtualPath += GetPicType(type);
 163:          else
 164:              VirtualPath += ServerPic + "NoPic.jpg";
 165:          
 166:          WriteImg(context, VirtualPath + fileName);//输出图片
 167:      }
 168:      /// <summary>
 169:      /// 获得图片的尺寸类别(small,middle,Big)
 170:      /// </summary>
 171:      /// <param name="Type">类别</param>
 172:      /// <returns></returns>
 173:      public string GetPicType(string Type)
 174:      {
 175:          string Directory="";
 176:          switch (Type)
 177:          {
 178:              case "Small":
 179:                  Directory = "Small/";
 180:                  break;
 181:              case "medium":
 182:                  Directory = "";
 183:                  break;
 184:              case "Big":
 185:                  Directory = "Big/";
 186:                  break;
 187:              default:
 188:                  break;
 189:          }
 190:          return Directory;
 191:      }
 192:      /// <summary>
 193:      /// 获得企业的图片
 194:      /// </summary>
 195:      /// <param name="context"></param>
 196:      public void GetCompanyPic(HttpContext context)
 197:      {
 198:          string type = context.Request["type"];//要访问的图片尺寸
 199:          string fileName = context.Request["fileName"];//文件名称
 200:   
 201:          string VirtualPath = ServerPic + "Company/MainCompanyPic/";//文件虚拟路径
 202:   
 203:          if (!Tools.IsValidInput(ref fileName, true))
 204:          {
 205:              return;
 206:          }
 207:          //真实路径
 208:          string PicTypeDirectory = GetPicType(type);
 209:          if (PicTypeDirectory != null)
 210:              VirtualPath += GetPicType(type);
 211:          else
 212:              VirtualPath += ServerPic + "NoPic.jpg";
 213:          
 214:          WriteImg(context, VirtualPath + fileName);//输出图片
 215:      }
 216:      /// <summary>
 217:      /// 输出图片信息
 218:      /// </summary>
 219:      /// <param name="context"></param>
 220:      public void WriteImg(HttpContext context,string FileName)
 221:      {
 222:          string path = context.Server.MapPath(FileName);
 223:          //获取图片文件的二进制数据。
 224:          Real(context, path);
 225:      }
 226:     /// <summary>
 227:      /// 按照文件类型输出
 228:     /// </summary>
 229:     /// <param name="context"></param>
 230:     /// <param name="fileName"></param>
 231:      private void Real(HttpContext context, string fileName)
 232:      {
 233:       
 234:          FileInfo file =new FileInfo(fileName);
 235:          if (file.Exists == false)
 236:          {
 237:              file = new FileInfo(ServerPic + "NoPic.jpg");
 238:          } 
 239:          context.Response.Clear();
 240:   
 241:          context.Response.AddHeader("Content-Disposition", "filename=" + file.Name);
 242:   
 243:          context.Response.AddHeader("Content-Length", file.Length.ToString());
 244:   
 245:          string fileExtension = file.Extension.ToLower();
 246:   
 247:          //这里选择输出的文件格式
 248:   
 249:          //可以参考http://ewebapp.cnblogs.com/articles/234756.html增加对文件格式的支持.
 250:   
 251:          switch (fileExtension)
 252:          {
 253:   
 254:              case ".mp3":
 255:   
 256:                  context.Response.ContentType = "audio/mpeg3";
 257:   
 258:                  break;
 259:   
 260:              case ".mpeg":
 261:   
 262:                  context.Response.ContentType = "video/mpeg";
 263:   
 264:                  break;
 265:   
 266:              case ".jpg":
 267:   
 268:                  context.Response.ContentType = "image/jpeg";
 269:   
 270:                  break;
 271:   
 272:              case ".bmp":
 273:   
 274:                  context.Response.ContentType = "image/bmp";
 275:   
 276:                  break;
 277:   
 278:              case ".gif":
 279:   
 280:                  context.Response.ContentType = "image/gif";
 281:   
 282:                  break;
 283:   
 284:              case ".doc":
 285:   
 286:                  context.Response.ContentType = "application/msword";
 287:   
 288:                  break;
 289:   
 290:              case ".css":
 291:   
 292:                  context.Response.ContentType = "text/css";
 293:   
 294:                  break;
 295:   
 296:              default:
 297:   
 298:                  context.Response.ContentType = "application/octet-stream";
 299:   
 300:                  break;
 301:   
 302:          }
 303:          byte[] datas = System.IO.File.ReadAllBytes(file.FullName);
 304:          context.Response.ClearContent(); //需要输出图象信息 要修改HTTP头 
 305:          //context.Response.ContentType = "image/Jpeg";
 306:          //将二进制数据写入到输出流中。
 307:         // context.Response.OutputStream.Write(datas, 0, datas.Length);
 308:          context.Response.BinaryWrite(datas);
 309:          //context.Response.BinaryWrite(file.FullName);
 310:   
 311:          context.Response.End();
 312:   
 313:      }
 314:      public bool IsReusable {
 315:          get {
 316:              return false;
 317:          }
 318:      }
 319:   
 320:  }

看到代码,大家一定知道了,现在我们换一个服务器什么的,只需要改改ServerPic,甚至直接写到配置文件中,这样,方便简单,读取只需要这样,

image

我只需要,访问图片存取模块,GetImg.ashx,告诉它,我现在是取主要产品的图片方法

GetMainProductPic,中等尺寸的图片,文件名=xxxx,

哈哈,这个是,看了一点设计模式,有一些灵感,然后尝试着改动以前的模块,感觉效果蛮不错的,解决了好多问题

图片的上传也是同样的道理,我们上传图片,经常为了缓解服务器鸭梨,还要做很多图片的缩略图,小图片,中图片,大图片的,等等,我们控制住了图片存取的关卡,所有的改动就不会影响到调用者了.

   1:  <%@ WebHandler Language="C#" Class="FileUpload" %>
   2:   
   3:  using System;
   4:  using System.Web;
   5:  using System.IO;
   6:  public class FileUpload : IHttpHandler {
   7:      
   8:      public void ProcessRequest (HttpContext context) {
   9:   
  10:          String methodName = context.Request["method"];
  11:          if (!string.IsNullOrEmpty(methodName))
  12:              CallMethod(methodName, context);
  13:      }
  14:      /// <summary>
  15:      /// 根据业务需求调用不同的方法
  16:      /// </summary>
  17:      /// <param name="Method">方法</param>
  18:      /// <param name="context">上下文</param>
  19:      public void CallMethod(string Method, HttpContext context)
  20:      {
  21:          switch (Method)
  22:          {
  23:   
  24:              case "UpLoadMasterPic":
  25:                  UpLoadMasterPic(context);
  26:                  break;
  27:              case "UpLoadCompanyPic":
  28:                  UpLoadCompanyPic(context);
  29:                  break;
  30:              case "UpLoadProductPic":
  31:                  UpLoadProductPic(context);
  32:                  break;
  33:              default:
  34:                  return;
  35:   
  36:   
  37:          }
  38:      }
  39:      /// <summary>
  40:      /// 上传产品图片
  41:      /// </summary>
  42:      /// <param name="context"></param>
  43:      public void UpLoadProductPic(HttpContext context)
  44:      {
  45:          //上传图片到产品的主目录下
  46:          string filePath = context.Server.MapPath("../Pictures/Product/MainProductPic");
  47:          //返回的文件名
  48:          string outFileName;
  49:          //返回的json格式
  50:          string returnJson = Common.FileUpload.FileUploadSingle(context, filePath, out outFileName);
  51:          //135*135规格小图片保存
  52:          string small_pic_path = filePath + "/small/";
  53:          //调用缩略图算法
  54:          Common.pic_zip.getzip_pic(135, 135, filePath+"/", small_pic_path, outFileName);
  55:          string middle_pic_Path = filePath + "/middle/";
  56:          //308*305规格中等图片
  57:          Common.pic_zip.getzip_pic(308, 305, filePath + "/", middle_pic_Path, outFileName);
  58:          context.Response.Write(returnJson);
  59:      }
  60:      /// <summary>
  61:      /// 上传大师主图片
  62:      /// </summary>
  63:      /// <param name="context"></param>
  64:      public void UpLoadMasterPic(HttpContext context)
  65:      {
  66:              //上传图片到大师的主目录下
  67:          string filePath = context.Server.MapPath("../Pictures/Master/MainMasterPic");
  68:          //返回的文件名
  69:          string outFileName;
  70:          //返回的json格式
  71:          string returnJson = Common.FileUpload.FileUploadSingle(context, filePath, out outFileName);
  72:          //135*135规格小图片保存
  73:          string small_pic_path = filePath + "/small/";
  74:          //调用缩略图算法
  75:          Common.pic_zip.getzip_pic(135, 135, filePath + "/", small_pic_path, outFileName);
  76:          //308*305规格中等图片
  77:          // Common.pic_zip.getzip_pic(308, 305, filePath, middle_pic_path,outFileName );
  78:          context.Response.Write(returnJson);
  79:          
  80:         
  81:      }
  82:      /// <summary>
  83:      /// 上传企业主图片
  84:      /// </summary>
  85:      /// <param name="context"></param>
  86:      public void UpLoadCompanyPic(HttpContext context)
  87:      {
  88:          //上传图片到企业的主目录下
  89:          string filePath = context.Server.MapPath("../Pictures/Company/MainCompanyPic");
  90:          //返回的文件名
  91:          string outFileName;
  92:          //返回的json格式
  93:          string returnJson = Common.FileUpload.FileUploadSingle(context, filePath, out outFileName);
  94:          //135*135规格小图片保存
  95:          string small_pic_path = filePath + "/small/";
  96:          //调用缩略图算法
  97:          Common.pic_zip.getzip_pic(135, 135, filePath + "/", small_pic_path, outFileName);
  98:          //308*305规格中等图片
  99:          // Common.pic_zip.getzip_pic(308, 305, filePath, middle_pic_path,outFileName );
 100:          
 101:          context.Response.Write(returnJson);
 102:          
 103:      }
 104:      public bool IsReusable {
 105:          get {
 106:              return false;
 107:          }
 108:      }
 109:   
 110:  }

还有一个系统配置管理,这个模块,我已经设计出大致思路,不过因为很多模块没做完,所以这个延后了,以后再写.

这个配置管理,专门管理静态页面生成,系统缓存配置等等,还有一系列的,比如第三方支付平台

配置,邮件服务器配置,等等,所有的全部都由这个配置管理器管理...

还有一个很重要的模块,我想到了,但是一直没有一个很好的实现方法.

就是针对静态页面生成,URL重写的管理器,因为,我们的静态页面要想很好的管理,出现,路径的

问题,总是很慢烦,比如,我的新闻页面生成静态,可能几万,甚至几十万的页面,这时候,我们就需

要对他进行管理,单独建立文件夹,甚至,文件夹按照日志生成,所以,这个页面管理器,一直在想,

怎么设计的完美.而且我可以动态的设置页面什么时候静态化,所有的链接全部变成静态,什么

时候URL重写的规则变了,不影响整个网站,正在考虑怎么做.这里大体设计了一个思路.

在母版页中,js的路径是根据项目中的aspx页面动态的,而css的路径计算不是这样子

打个比方,母板页中,要通过全部转化为绝对路径的方式才能正确的索引到文件

image

如果相对路径,在子页面引用母板页,就会发生路径的不一致

因此,就会遇到,在生成静态页面,路径的问题...所以URL管理挺重要的.

今天的总结就到这里为止.

我的superui开源后台bootstrap开发框架github地址:https://github.com/tzhsweet/superui
原文地址:https://www.cnblogs.com/mysweet/p/2489402.html