上次简单的总结了三层构架,这次,总结关于项目架构方面的东西,哈!
第一个,当然是文件管理..
一个项目一个完整的目录结构,是一个很好的方式,就像asp.net MVC充满了美感.....
MVC项目的整体结构非常清晰,我们就要借鉴这种方式,
从建立文件开始,规范,
可以看到,目录清晰,非常容易对各个模块进行管理,也非常适合了解整个网站架构
整个网站目录架构是一个网站的细节,越清晰越容易后期维护和开发.
在这里面涉及到几个很重要的地方:
1.系统日志管理和系统日志
2.文件存取管理
3.系统配置管理
可以说,这三个模块什么网站都可以加进去,这三个模块,具体干什么的呢?
系统日志管理.
主要是记录系统的程序运行异常信息(Log4net框架),还有一个就是系统操作的日志
系统异常日志,方便程序员调试,而且记录系统所有的异常.
系统操作的日志,管理员登录后台以后,做的所有操作都记录下来(这个大家都懂的....哈哈....)
文件存取管理
很多数时候,我们数据库存取图片,保存图片路径(使用相对路径的方式),然后,本地这么调用
但是,这种方式,简直就是坑爹,如果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,甚至直接写到配置文件中,这样,方便简单,读取只需要这样,
我只需要,访问图片存取模块,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的路径计算不是这样子
打个比方,母板页中,要通过全部转化为绝对路径的方式才能正确的索引到文件
如果相对路径,在子页面引用母板页,就会发生路径的不一致
因此,就会遇到,在生成静态页面,路径的问题...所以URL管理挺重要的.
今天的总结就到这里为止.