日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

《ASP.NET辦公自動化系統(tǒng)開發(fā)實例導(dǎo)航》筆記二 系統(tǒng)管理模塊設(shè)計

 liuqg 2006-03-10
《ASP.NET辦公自動化系統(tǒng)開發(fā)實例導(dǎo)航》筆記二 系統(tǒng)管理模塊設(shè)計 Posted on 2005-11-03 17:19 wddavid 閱讀(823) 評論(3)  編輯 收藏 收藏至365Key 所屬分類: .NET
首先設(shè)計的是[系統(tǒng)管理]模塊,這也是一般系統(tǒng)的步驟.
簡略的UML活動圖如下:


數(shù)據(jù)庫有:
登錄日志信息表LogInfo
操作日志信息表sysOptLog
機構(gòu)基本信息表mrBranch
部門基本信息表mrDepartment    [機構(gòu)比部門大一級,機構(gòu)可以包括多個部門]
人員基本信息表mrBaseInf    [也就是用戶表]
模塊基本信息表sysFuncDic
角色基本信息表sysRolesDic
用戶角色關(guān)系表sysEmpRoles
模塊角色關(guān)系表sysFuncRights
目錄基本信息表sysTab

一個用戶可以對應(yīng)多個角色,而一個角色可以包含多個用戶:一個角色可以包含多個模塊,一個模塊也可以對應(yīng)多個角色.所以,他們?nèi)慷际嵌鄬Χ嗟年P(guān)系,可以處理復(fù)雜的權(quán)限問題.

一.管理登錄日志

對SQL操作全部使用存儲過程.;對所有的頁面全部繼承基類PageBase.cs
1.通用類中用到一個比較常用的函數(shù):(刪除不可見字符函數(shù))
public static string DeleteUnVisibleChar(string sourceString)
        {
            System.Text.StringBuilder sBuilder 
= new System.Text.StringBuilder(131);
            
for(int i = 0;i < sourceString.Length; i++)
            {
                
int Unicode = sourceString[i];
                
if(Unicode >= 16)
                {
                    sBuilder.Append(sourceString[i].ToString());
                }                
            }
            
return sBuilder.ToString();
        }

2.自由操縱DataGrid.
可以使用一些技巧來自由操縱DataGrid:
(1)比如要在每行頭部加入CheckBox,可以加入一個模板列,模板中放入一個CheckBox控件:
<asp:TemplateColumn>
    
<ItemTemplate>
        
<asp:CheckBox id="CheckBox1" runat="server"></asp:CheckBox>
    
</ItemTemplate>
</asp:TemplateColumn>
其他的綁定列不要變,這樣就會出現(xiàn)一個CheckBox,比如用于選中的多項刪除操作.但是如何在程序中實現(xiàn)刪除操作呢?首先將datagrid的DataKeyField關(guān)鍵字段設(shè)置為要刪除所需的關(guān)鍵字段(比如用戶ID),然后在刪除處理時,通過對每行的第一列的第一個控件(即CheckBox,但沒有ID,所以必須這樣做)來判斷:
                foreach(DataGridItem thisItem in DataGridLogininfo.Items)
                {
                    
if(((CheckBox)thisItem.Cells[0].Controls[1]).Checked)    //表示此一行的第一列中的第一個控件
                    {
                        
string strLoginID = DataGridLogininfo.DataKeys[thisItem.ItemIndex].ToString();    //設(shè)定DataGridLogininfo的DataKeyField為LoginID
                    
                        DelLoginLog(strLoginID);
                    }
                }
這樣,"全部選中"的CheckBox2的代碼也簡單了:
            foreach(DataGridItem thisItem in DataGridLogininfo.Items)
            {
                ((CheckBox)thisItem.Cells[
0].Controls[1]).Checked = CheckBox2.Checked;
            }

同樣,我們可以擴展,比如為每條記錄前面加個序號,如何加?
有兩種方法:
第一種,和前面一樣,加一個模板列,用一個頁面全局變量的number++;
第二種,對綁定前得到的DataTable進行處理,加入一列:
            DataTable    mytable=myclass.Getalllogininfo ();
            DataColumn  mycolumn
=  mytable.Columns.Add ("number",System.Type .GetType ("System.String"));    //在數(shù)據(jù)源DataTable中加入一列,注意技巧
            for (int i=0;i<mytable.Rows.Count ;i++)
            {
                mytable.Rows [i][
"number"]=(i+1).ToString ();
            }
這是一個很重要的方法,如果要對綁定數(shù)據(jù)實現(xiàn)復(fù)雜的操作,常常要用到這個原理.

還有,如何加入比較復(fù)雜的功能,比如,鼠標(biāo)到每一條記錄上都變色呢?
這個可以通過DataGrid的ItemDataBound事件來處理,可以給每一項加上屬性,方法如下:
        //綁定Javascript腳本到每行,是鼠標(biāo)指向時顏色變化
        private void DataGridLogininfo_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
        {
            ListItemType itemType 
= e.Item.ItemType;
            
if (itemType == ListItemType.Item )
            {
                
                e.Item.Attributes[
"onmouseout"= "javascript:this.style.backgroundColor=‘#dedfde‘;";
                e.Item.Attributes[
"onmouseover"= "javascript:this.style.backgroundColor=‘#fff7ce‘;cursor=‘hand‘;" ;

            }
            
else if( itemType == ListItemType.AlternatingItem)
            {
                e.Item.Attributes[
"onmouseout"= "javascript:this.style.backgroundColor=‘#ffffff‘;";
                e.Item.Attributes[
"onmouseover"= "javascript:this.style.backgroundColor=‘#fff7ce‘;cursor=‘hand‘;" ;
            }
        }


二.管理操作日志
與上面一個沒什么區(qū)別,同樣要利用PageBase的PageBegin方法,這樣可以確定所在的模塊并檢查權(quán)限,頁面基類的好處已經(jīng)體現(xiàn)出來了.

視圖狀態(tài)ViewState在ASP.NET里是默認(rèn)存在的,在表單的發(fā)送之間幾乎所有的ASP.NET控件都會保留屬性值.它實際上就是一個隱藏的表單域,即HIDDEN的INPUT.

為服務(wù)器控件添加javascript腳本:
Button1.Attributes.Add("onclick""javascript:alert(‘cool!‘");


三.模塊管理
模塊管理再次證明了一點:只有想不到,沒有做不到的.
里面對于權(quán)限的DataList綁定CheckBoxList的復(fù)雜處理可謂精彩絕倫.

如果對于綁定到DataList等里面的控件操作,一般都要使用
(ControlType)DataList.Items[Index].FindControl("ControlName")來取得控件,然后進行處理.

對于命令按鈕,都要設(shè)置CommandName,然后在DataList_ItemCommand里面通過判斷來進行處理,所以CommandName不僅僅是可以用edit或delete,還可以多種多樣,處理十分靈活.

由于類中的連接常常是局部變量,外部調(diào)用時不可能關(guān)閉,所以用
DataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
這樣自動關(guān)閉連接比較實用.

四.目錄管理
這里主要有一個知識點:如果編輯比較簡單,可以直接用DataGrid的自有編輯方法:
這里,主要有dgCatalog_EditCommand,dgCatalog_DeleteCommand,dgCatalog_CancelCommand,dgCatalog_UpdateCommand這幾個事件.同樣,都是先取得DataKey關(guān)鍵字,然后進行處理;Update的時候,同樣是取得(TextBox)Cells[0].Controls[1].Text這樣的值,然后再運行存儲過程等等更新.

Feedback

# 邏輯層和數(shù)據(jù)層劃分  回復(fù)   

2005-11-04 08:03 by wddavid
這里,只有目錄模塊用了邏輯層,而且邏輯層的處理也非常簡單,就是把數(shù)據(jù)層處理返回值.
比如:
public bool UpdateCatalog(CatalogData catalogData)
{
CatalogDB CatalogAccess = new CatalogsDB();
return CatalogAccess.UpdateLog(catalogData);
}
直接調(diào)用數(shù)據(jù)層的就完事了.
我們前面把處理都放在數(shù)據(jù)層主要是數(shù)據(jù)比較簡單,不需要增加邏輯層來復(fù)雜操作.但是這里為什么又增加呢?
主要因為一點:擴展性.雖然這里對數(shù)據(jù)沒有任何處理,只是將表示層的數(shù)據(jù)直接傳給下一層數(shù)據(jù)層,這里加入這一層是為了以后業(yè)務(wù)層擴展使用,根據(jù)業(yè)務(wù)層的需要,表示層傳來的數(shù)據(jù)可以經(jīng)過業(yè)務(wù)邏輯層的加工再傳給數(shù)據(jù)層.
(比如,如果將來目錄的一些路徑改變了,這里就必須進行處理,而不需要去修改數(shù)據(jù)層,數(shù)據(jù)層一般只處理對處理好的數(shù)據(jù)的數(shù)據(jù)庫操作)

# 基類PageBase再探  回復(fù)   

2005-11-08 08:26 by wddavid
本系統(tǒng)中的PageBase類主要也只有幾點作用:

1.提供初始化方法PageBegin,那么我們在每個頁面Page_Load里面都調(diào)用它,形式:
Public void PageBegin(moduleName, isCheck)
moduleName我們根據(jù)每個頁面的不同寫模塊名稱,isCheck為了靈活處理,如果不需要檢驗權(quán)限的頁面則isCheck參數(shù)為false.這樣,根據(jù)取得Session["EmpID"]來判斷對于現(xiàn)在模塊moduleName的權(quán)限,如果不夠就RedirectTo Login.aspx.

2.寫入操作日志.由于操作日志要確定操作員和模塊名稱,所以每個頁面不一樣,所以把其放入PageBase里.

3.錯誤處理.
唯一的PageBase中處理的Page事件:
protected void PageBase_Error(object sender, System.EventArgs e)
里面用EventLog.WriteEntry寫入系統(tǒng)日志.

# 繼承DataSet的信息類和手動建立DataAdapter的Command  回復(fù)   

2005-11-08 08:37 by wddavid

下面這個是目錄模塊信息類CatalogData:

 public class CatalogData : DataSet //繼承DataSet,這樣可以擁有成員Tables來返回DataTable
 {
  //表格名稱,其實這些最好用public static readonly string ...來代替
  public const string CATALOG_TABLE_NAME = "CatalogData";

  public const string PK_FIELD = "pkid";
  public const string TABID_FIELD = "tabid";
  public const string INDEXID_FIELD = "indexid";
  public const string NAME_FIELD = "name";
  public const string DESCRIPTION_FIELD = "description";
  public const string URL_FIELD = "url";

  //構(gòu)造函數(shù)
  public CatalogData()
  {
   BuildTable();
  }
  //創(chuàng)建數(shù)據(jù)結(jié)構(gòu)表格
  private void BuildTable()
  {
   DataTable table = new DataTable(CATALOG_TABLE_NAME);
   DataColumnCollection cols = table.Columns; //同指向table的Columns,對列和行的集合就是DataColumnCollection和DataRowCollection
   cols.Add(PK_FIELD,typeof(System.Int16)); //列的表示:(名稱, 類型)
   cols.Add(TABID_FIELD,typeof(System.String));
   cols.Add(INDEXID_FIELD,typeof(System.String));
   cols.Add(NAME_FIELD,typeof(System.String));
   cols.Add(DESCRIPTION_FIELD,typeof(System.String));
   cols.Add(URL_FIELD,typeof(System.String));
   Tables.Add(table); //這樣,新建的CatalogData類就有了一個CatalogData.Tables[CatalogData.CATALOG_TABLE_NAME]的DataTable
  }
 }

注釋中已經(jīng)說明了這種定義的一些特點:
同理,我們在數(shù)據(jù)層的應(yīng)用中,對于Update,Insert等各種方法,使用了下面的方法:
  public bool UpdateCatalog(CatalogData catalogData)
  {
   commandAdp.UpdateCommand = GetCommand();

   //因為插入的GetCommand()取得命令不需要pkid,所以pkid參數(shù)單獨加入
   commandAdp.UpdateCommand.Parameters.Add(new SqlParameter(paramChg(CatalogData.PK_FIELD),SqlDbType.Int));
   commandAdp.UpdateCommand.Parameters[paramChg(CatalogData.PK_FIELD)].SourceColumn = CatalogData.PK_FIELD;

   commandAdp.UpdateCommand.CommandText = "UpdateCatalogs";
   commandAdp.Update(catalogData,CatalogData.CATALOG_TABLE_NAME); //同更新DataSet (catalogData)

   if(catalogData.HasErrors) //繼承DataSet的是否含有錯誤
   {
    catalogData.Tables[CatalogData.CATALOG_TABLE_NAME].GetErrors()[0].ClearErrors();
    return false;
   }
   else
   {
    //catalogData.AcceptChanges(); //Update(DataSet)后其實不用DataSet.AcceptChanges
    return true;
   }
  }

    public bool CreateCatalog(CatalogData catalogData)
    {
     commandAdp.InsertCommand = GetCommand();
     commandAdp.InsertCommand.CommandText = "InsertCatalog";
 
     commandAdp.Update(catalogData,CatalogData.CATALOG_TABLE_NAME);

     if(catalogData.HasErrors)
     {
      catalogData.Tables[CatalogData.CATALOG_TABLE_NAME].GetErrors()[0].ClearErrors();
      return false;
     }
     else
     {
      catalogData.AcceptChanges();
      return true;
     }
    }

  private SqlCommand GetCommand()
  {
   SqlCommand command = new SqlCommand();

   command.Connection = con;
   command.CommandType = CommandType.StoredProcedure;

   SqlParameterCollection param = command.Parameters;

   param.Add(new SqlParameter(paramChg(CatalogData.TABID_FIELD),SqlDbType.VarChar));
   param.Add(new SqlParameter(paramChg(CatalogData.INDEXID_FIELD),SqlDbType.VarChar));
   param.Add(new SqlParameter(paramChg(CatalogData.NAME_FIELD),SqlDbType.VarChar));
   param.Add(new SqlParameter(paramChg(CatalogData.DESCRIPTION_FIELD),SqlDbType.VarChar));
   param.Add(new SqlParameter(paramChg(CatalogData.URL_FIELD),SqlDbType.VarChar));

   //設(shè)置源列的名稱并設(shè)置參數(shù)值
   param[paramChg(CatalogData.TABID_FIELD)].SourceColumn = CatalogData.TABID_FIELD;
   param[paramChg(CatalogData.INDEXID_FIELD)].SourceColumn = CatalogData.INDEXID_FIELD;
   param[paramChg(CatalogData.NAME_FIELD)].SourceColumn = CatalogData.NAME_FIELD;
   param[paramChg(CatalogData.DESCRIPTION_FIELD)].SourceColumn = CatalogData.DESCRIPTION_FIELD;
   param[paramChg(CatalogData.URL_FIELD)].SourceColumn = CatalogData.URL_FIELD;

   return command;
  }
  /* 注意,上面生成的是DataAdapter.UpdateCommand.
   * 一般來說,我們都使用自動生成法:
   * 如果用于檢索填充 DataSet 的數(shù)據(jù)的 SELECT 語句基于單個數(shù)據(jù)庫表,則可利用 CommandBuilder 對象自動生成
   *  DataAdapter 的 DeleteCommand、InsertCommand 和 UpdateCommand 屬性。 這將簡化并減少執(zhí)行插入、更新和刪除操作所必需的代碼。
   * 也就是說,比如:
   * ada.SelectCommand.CommandText = "select * from table";
   * SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(ada);
   * 這樣,就可以使用Update命令:ada.Update(dataSet, tableName);
   * 如果要手動生成,則要象上面一樣,設(shè)置param,并要設(shè)置每個param對應(yīng)表中的列名,即SourceColumn.(還有一個SourceVersion,來決定是用新值還是舊值,一般較少用)
   */

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多