博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一些开发中常见的简单问题

Posted on 2009-02-27 14:53  a-peng  阅读(318)  评论(0编辑  收藏  举报

首先推荐下Community Server,这个大家再熟悉不过了,给出最新版的下载地址。

Community Server 源码最新版下载http://get.communityserver.com/download/moredownloads.aspx

你可以找到:

Community Server Developers

Community Server 2008.5Software Developer Kit(SDK) 因为开发版才有源码。

 

一、Add,Edit只要一个页面就可以了

web site通常都避免不了CRUD,页面类型通常有ListDetailAddEditDel5种。

怎样做会比较合理且方便呢?

AddEdit这两种类型页面通常可以通用。通过Edit.aspx?action=add Add)与Edit.aspx?action=edit&id=xxxEdit)来区分二者有点没有必要。可以直接使用Edit.aspxAdd)与Edit.aspx?id=xxxEdit

 

CommunityServer.Web下有个SiteUrls.config文件,其中包含了CommunityServer的站点结构。

<?xml version="1.0" encoding="utf-8" ?>

<SiteUrls>

<location name="controlpanel" path="/controlpanel/" exclude = "true" applicationType="admin">

         <!-- ControlPanel paths -->

         <url name="controlpanel"  path="default.aspx" />

<url name="controlpanel_loading"  path="loading.aspx?msg={0}" />

 

<!-- Forums Control Panel Pages -->

       <url name="forums_ControlPanel_Home"  path="forums/" />

       <url name="forums_ControlPanel_NewForum"  path="forums/SectionEdit.aspx" />

       <url name="forums_ControlPanel_NewGroup"  path="forums/GroupEdit.aspx" />

       <url name="forums_ControlPanel_EditForum"  path="forums/SectionEdit.aspx?SectionID={0}" />

       <url name="forums_ControlPanel_EditGroup"  path="forums/GroupEdit.aspx?GroupID={0}" />

       <url name="forums_ControlPanel_ForumList"  path="forums/Forums.aspx" />

       <url name="forums_ControlPanel_Created_ForumList"  path="forums/Forums.aspx?SectionID={0}" />

       <url name="forums_ControlPanel_ForumListByGroup"  path="forums/Forums.aspx?GroupID={0}" />

       <url name="forums_ControlPanel_GroupList"  path="forums/ForumGroups.aspx" />

       <url name="forums_ControlPanel_SortOrder"  path="forums/SortOrder.aspx" />

       <url name="forums_ControlPanel_DefaultPermissionList"  path="forums/DefaultPermissionList.aspx" />

<url name="forums_ControlPanel_PostOptions"  path="forums/options/PostOptions.aspx" />

</location>

</SiteUrls>

 

仔细查看这个xml,你会发现结构真的很清晰。

forums_ControlPanel_NewForum 对应 forums/SectionEdit.aspx Add

forums_ControlPanel_EditForum 对应 forums/SectionEdit.aspx?SectionID={0}Edit

 

二、 Url参数的处理

期望Url

http://localhost/cs/controlpanel/forums/SectionEdit.aspx?SectionID=1 (正常)(Edit

http://localhost/cs/controlpanel/forums/SectionEdit.aspx (正常)(Add

非期望Url

http://localhost/cs/controlpanel/forums/SectionEdit.aspx?SectionID=xxx (正常)(Add

http://localhost/cs/controlpanel/forums/SectionEdit.aspx?xxx=xxx (正常)(Add

等等,你会发现Community ServerUrl参数的处理很稳定。

 

有很大一部份朋友会使用如下方式:

private int id;

protected void Page_Load(object sender, EventArgs e)

{

if (!string.IsNullOrEmpty(Request.QueryString["id"])) // edit

{

id = int.Parse(Request.QueryString["id"]);

}

else // add

{          

 

}

}

 

这样会有很多麻烦事,比如传入的idint类型,会抛异常,而且这种需求太常见了,到处放try-catch也不是很好。

让我们来看看community server的作法

private int sectionID;

     private bool isNew

     {

         get{return sectionID <= 0;}

}

private void Page_Load(object sender, EventArgs e)

     {

         context = CSContext.Current;

 

         if( !context.User.IsForumAdministrator )

              throw new CSException(CSExceptionType.AdministrationAccessDenied);

 

         sectionID = context.GetIntFromQueryString("SectionID", -1);

         

if (isNew)

         {

          }

          else

          {

         }

     }

 

把类型转换的异常在GetIntFromQueryString里就处理掉,所以如果传入的参数是SectionID=xxx,也不会抛异常。只会返回-1,也就是传入的默认值。

我想这种方式是很值得借鉴使用的,而且整个代码都非常的漂亮美观。

 

至于context.GetIntFromQueryString这个类要怎么编写就看个人了。像Discuz!NT是封装成一个帮助类。CommunityServer有些不是区别的区别。

大体都差不多。


刚刚听了一个很不错的建意。就是获取Request.QueryString。比如上面获取sectionID都是在Page_Load方法中取得,但是这个职责并不属于Page_Load。而且要是改动的话,比如对Request.QueryString的值做判断的话,改动的地方可能会比较多。而且也不直观方便。推荐的作法是放到属性Section中,直接在属性中获取与判断值。如下:

public int SectionID

{

  get{return context.GetIntFromQueryString("SectionID", -1);}

}

 

三、数据层CRUD的编写

CUD Community Server通常都是采用如下这种方式

public override int CreateUpdateDeleteGroup(Group group, DataProviderAction action) {

 

}

 

DataProviderAction为枚举:CreateUpdateDeleteNoSet

 

Community Server在架构上支持多数据库,通过上面的override就可以看出来,不过是面向抽象类,不是面向接口。

把一些多数据库都支持的方法放在抽象类中,省了些重复的代码。

不过Community Server只是实现了Sql Server数据库,其它数据库并没有实现。

Community Server在这里主要是把操作嫁接到数据库中,将action做为参数传入到存储过程中。

所以如果实现Access数据库的话,这个方法可能就会长一点。

 

不过我是很喜欢这种规到一起的方式,然后在逻辑层分开。

 

还有就是枚举在开发中是非常好用的,不要浪费到了噢。

不过最好要有统一的命名比如在名称后加TypeEnum来区分感觉会好点。

四、杂七杂八

分层不是越多越好,这个毛病是很多刚接触分层的朋友经常犯的。

CommunityServer的设计有很多可以学习的地方。

不过CommunityServer.Components项目下的命名空间有点恐怖。

比如Common文件夹的命名空间成了namespace CommunityServer.Common

比如Components文件夹的命名空间成了namespace CommunityServer.Components

 

小菜之前也干过一种更疯狂的作法如下:

AA.Library项目 命名空间 namespace AA.Library

     Configuration文件夹 命名空间 namespace AA.Library

     Enumeration文件夹 命名空间 namespace AA.Library

     Helpers文件夹 命名空间 namespace AA.Library

     等等文件夹

命名空间只使用AA.Library,这样用起来很方便,只要引用一个命名空间就可以了。

不过这种作法是强烈反对的。

 

比如AA.Library下的类一定会很多。你AA.Library智能提示会出现多少个类?单纯从你找类的角度就麻烦。

微软的MVC下的命名空间是怎么划分的?

Controler/View/Model

所以如下会比较好

AA.Library项目 命名空间 namespace AA.Library

     Configuration文件夹 命名空间 namespace AA.Library.Configuration

     Enumeration文件夹 命名空间 namespace AA.Library.Enumeration

     Helpers文件夹 命名空间 namespace AA.Library.Helpers

     等等文件夹

 

 

说到这里就顺便说下在Linq中的一些注意地方

 

1最好使用FistOrDefault而不要使用SingleOrDefault免的出错。

2在使用GetAll().FirstOrDefault或者GetAll().Where等等先要判断GetAll()是否为空。