NASA(Net Application Scaleable Architecture)作为企业级应用系统开发的框架,包括数据访问组件,控件库,日志服务和Web应用的基础模块(用户角色管理,菜单设置,资源管理,页面配置)等。
经过两年多时间的修改,大大小小项目的实践,基本上已形成完善的结构。刚开始的时候UI使用DevExpress控件,功能很强大,但性能不太理想,后来开始开发一些常用的.NET控件,查询控件、数据表格、编辑控件都可支持用户或者实施人员配置。数据访问组件支持多种数据库,以一个开源的项目为基础进行修改,优化了生成的SQL的性能。把数据库中的表和视图转化为C#的对象,使用这些C#的对象生成SQL并执行,其性能比NHibernate / Entrity Framework都优胜。
NASA支持分布式应用系统,可以根据服务器硬件,把系统发布到多个物理层。使用三层结构,可调用其它服务提供的功能。分层结构图:

NASA工程项目图:

- Nasa.App
The core lib of the Application. Include Schema / DTOs / Application Logical Interfaces and default implements. Advanced implement can be integrated through the configuration file.
- Nasa.App.Web
Presentation tier of the Application.
1.Ext JS 2.3(free) and ASP.NET Controls.
2.Multi –Languages. (zh-CN, en-us, zh-TW, …)
3.Themes and Skins. (Aqua)
4.Cross-browser.(IE 5.5+, Firefox, Chrome, …)
5.Customize Search and Result displaying.
6.Favorite & Fast Create
7.Help for each page.
- Nasa.Data
Data Access Component.
1.Providers for Oracle / MSSQL / Access. (DB2 / MySQL optional)
2.Entity base.
3.N-Tier Undo-Redo model base. (for winform application)
4.Validation tools.
5.Special Collections.
- Nasa.Web.UI
The UI component library. Extend from the ASP.NET Controls.
1.ASPxGridView
A.Enhanced from GridView. Special for data displaying.
B.Can suppress the row viewstate.
C.Support multi-pages Selection.
2.ASPxEditView
A.Enhanced from DetailsView. Special for data editing.
B.Can be layout in multi-columns.
C.Support enhanced DataControlFields.
D.Invalid prompt.
3.Enhanced Editors, server-site controls, support validation prompt
A.ASPxComboBox
B.ASPxDatePicker
C.ASPxNumericBox
D.ASPxTextBox
E.ASPxTextArea
F.ASPxCheckBoxList
F.ASPxCheckBoxList
...
- Nasa.Utils
Utilities. Helpers for Sending Email, Data Export / Import, Log and Cryptography.
- Nasa.LogService
Include Log Service(WCF) and Log Viewer. It can work for multi-platforms and multi-applications. You can manage your Application through the priority level event log.
NASA Web界面截图:




数据显示页面Nasa.App.Web/Init/Entry/Default.aspx的代码:
1 <%@ Page Title="" Language="C#" MasterPageFile="~/Core/Master/MainMaster.Master"
2 AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Nasa.App.Web.Init.Entry.Default" %>
3
4 <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
5 </asp:Content>
6 <asp:Content ID="Content2" ContentPlaceHolderID="SearchContent" runat="server">
7 <ASPx:ASPxFilterControl runat="server" ID="filter" OnInit="filter_Init">
8 </ASPx:ASPxFilterControl>
9 <asp:ObjectDataSource ID="odsModel" runat="server" DataObjectTypeName="Nasa.App.Init.Entry.InitEntryModel"
10 SelectMethod="GetModels" DeleteMethod="DeleteModel" TypeName="Nasa.App.Web.Init.Entry.Default">
11 <SelectParameters>
12 <asp:ControlParameter ControlID="filter" Name="criteria" PropertyName="Value" Type="Object" />
13 </SelectParameters>
14 </asp:ObjectDataSource>
15 </asp:Content>
16 <asp:Content ID="Content3" ContentPlaceHolderID="ToolBarContent" runat="server">
17 <ASPx:ToolBar ID="toolBar" runat="server" OnInit="toolBar_Init">
18 <buttonsearch onclick="toolBar_SearchClick"></buttonsearch>
19 <buttonclear onclientclick="filter.Clear();" autopostback="false"></buttonclear>
20 <buttoncreate onclientclick="openEdit('');" autopostback="false"></buttoncreate>
21 <buttondelete onclick="toolBar_DeleteClick"></buttondelete>
22 <buttonexport onclick="toolBar_ExportClick"></buttonexport>
23 </ASPx:ToolBar>
24 </asp:Content>
25 <asp:Content ID="Content4" ContentPlaceHolderID="MainContent" runat="server">
26 <ASPx:ASPxGridView ID="grid" runat="server" DataSourceID="odsModel" DataKeyNames="Id"
27 OnInit="grid_Init" EditNavigateUrlFormatString="javascript:openEdit('{0}');"
28 AutoGenerateColumns="false">
29 </ASPx:ASPxGridView>
30 <script type="text/javascript">
31 function openEdit(key) {
32 JSOpen('<%=EditTabId%>', '<%=EditTabTitle%>', "<%=EditPath%>?key=" + key, true);
33 }
34 function performSearch() {
35 JSGet('<%=toolBar.ButtonSearch.ClientID%>').click();
36 }
37 parent.window["<%=ModuleID.ToString()%>"] = performSearch;
38 </script>
39 </asp:Content>
40 <asp:Content ID="Content5" ContentPlaceHolderID="FooterContent" runat="server">
41 <ASPx:PagerBar ID="pagerBar" ASPxGridViewID="grid" runat="server" />
42 </asp:Content>
数据显示页面Nasa.App.Web/Init/Entry/Default.aspx.cs的代码:
1 using System;
2 using Nasa.App.Init.Entry;
3 using Nasa.App.Web.Core;
4 using Nasa.Data;
5
6 namespace Nasa.App.Web.Init.Entry
7 {
8 public partial class Default : BasePage
9 {
10 IInitEntryManager manager = CreateRefObj<IInitEntryManager>();
11
12 public override Module ModuleID
13 {
14 get { return Module.InitEntry; }
15 }
16
17 protected override string DataObjectTypeName
18 {
19 get { return odsModel.DataObjectTypeName; }
20 }
21
22 protected void Page_Load(object sender, EventArgs e)
23 {
24
25 }
26
27 protected void toolBar_SearchClick(object sender, EventArgs e)
28 {
29 grid.RefreshData();
30 }
31
32 protected void toolBar_DeleteClick(object sender, EventArgs e)
33 {
34 BatchDelete(grid);
35 }
36
37 protected void toolBar_ExportClick(object sender, EventArgs e)
38 {
39 Utils.ExportOptions opt = new Utils.ExportOptions();
40 Export(grid, toolBar.GetExportType(), opt);
41 }
42
43 [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
44 public InitEntryModels GetModels(QueryCriteria criteria)
45 {
46 if (!CanRead)
47 throw GetNotAuthorizationException();
48 ((GroupOperator)criteria).Operands
49 .Add(new BinaryOperator("Type", -1, BinaryOperatorType.NotEqual));
50 return manager.GetModels(criteria);
51 }
52
53 [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Delete)]
54 public void DeleteModel(InitEntryModel model)
55 {
56 if (!CanDelete)
57 throw GetNotAuthorizationException();
58 manager.DeleteModel(model);
59 }
60
61 [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
62 public KeyTextList GetEntry(int type)
63 {
64 return manager.GetEntry(type);
65 }
66 }
67 }
数据编辑页面Nasa.App.Web/Init/Entry/Edit/Default.aspx的代码:
1 <%@ Page Title="" Language="C#" MasterPageFile="~/Core/Master/DetailMaster.Master"
2 AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Nasa.App.Web.Init.Entry.Edit.Default" %>
3
4 <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
5 </asp:Content>
6 <asp:Content ID="Content2" ContentPlaceHolderID="ToolBarContent" runat="server">
7 <ASPx:EditToolBar ID="editToolBar" runat="server">
8 <buttonsave onclick="editToolBar_SaveClick"></buttonsave>
9 <buttonundo onclick="editToolBar_UndoClick"></buttonundo>
10 <buttoncreate onclick="editToolBar_CreateClick"></buttoncreate>
11 <buttongrid onclientclick="openView();" autopostback="false"></buttongrid>
12 </ASPx:EditToolBar>
13 </asp:Content>
14 <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
15 <ASPx:ASPxEditView ID="view" runat="server" AutoGenerateRows="False" DataSourceID="odsModel"
16 OnInit="view_Init" DataKeyNames="Id">
17 <Columns>
18 <ASPx:ASPxTextBoxField DataField="Key" HeaderText="EntryKey">
19 </ASPx:ASPxTextBoxField>
20 <ASPx:ASPxTextBoxField DataField="Value" HeaderText="EntryValue">
21 </ASPx:ASPxTextBoxField>
22 <ASPx:ASPxTemplateField Name="Type" HeaderText="EntryType">
23 <ItemTemplate>
24 <table cellpadding="0" cellspacing="0">
25 <tr>
26 <td>
27 <ASPx:ASPxComboBox runat="server" ID="cbxType" DataValueField="Key" DataTextField="Text"
28 NullText=" " NullValue="0" DataSourceID="odsType" SelectedValue='<%#Bind("Type") %>'>
29 </ASPx:ASPxComboBox>
30 <asp:ObjectDataSource ID="odsType" TypeName="Nasa.App.Web.Init.Entry.Edit.EntryType"
31 runat="server" SelectMethod="GetEntryType"></asp:ObjectDataSource>
32 </td>
33 <td style="padding-left: 5px">
34 <asp:HyperLink runat="server" ID="lnkLanEdit" SkinID="FormEdit" NavigateUrl="javascript:openForm();">
35 </asp:HyperLink>
36 </td>
37 </tr>
38 </table>
39 </ItemTemplate>
40 </ASPx:ASPxTemplateField>
41 <ASPx:ASPxTextAreaField DataField="Remark" HeaderText="Remark">
42 </ASPx:ASPxTextAreaField>
43 <ASPx:ASPxCheckBoxField DataField="Active" HeaderText="Active">
44 <EditControl Checked="true" />
45 </ASPx:ASPxCheckBoxField>
46 <ASPx:ASPxComboBoxField HeaderText="UpdateUser" DataField="UpdateUser" ReadOnly="true"
47 InsertVisible="false">
48 <EditControl DataSourceID="odsUser" DataTextField="Text" DataValueField="Key">
49 </EditControl>
50 </ASPx:ASPxComboBoxField>
51 <ASPx:ASPxDatePickerField DataField="UpdateDate" ReadOnly="true" InsertVisible="false"
52 HeaderText="UpdateDate" DataFormatString="yyyy-MM-dd HH:mm:ss">
53 </ASPx:ASPxDatePickerField>
54 </Columns>
55 </ASPx:ASPxEditView>
56 <asp:ObjectDataSource ID="odsUser" runat="server" SelectMethod="GetUserList" TypeName="Nasa.App.Web.Init.User.Default">
57 </asp:ObjectDataSource>
58 <asp:ObjectDataSource ID="odsModel" runat="server" DataObjectTypeName="Nasa.App.Init.Entry.InitEntryModel"
59 InsertMethod="AddModel" SelectMethod="GetModel" TypeName="Nasa.App.Web.Init.Entry.Edit.Default"
60 UpdateMethod="UpdateModel">
61 <SelectParameters>
62 <asp:ControlParameter ControlID="editKey" DefaultValue="" Name="key" PropertyName="value"
63 Type="String" />
64 </SelectParameters>
65 </asp:ObjectDataSource>
66 <asp:HiddenField runat="server" ID="editKey" />
67 <script type="text/javascript">
68 function openView() {
69 JSOpen('<%=(int)ModuleID %>', '<%=TabTitle %>', "<%=QueryPath %>", false, parent.window["<%=ModuleID.ToString()%>"]);
70 }
71 function openForm() {
72 JSOpenForm('<%=GetText(Nasa.App.Module.InitEntryType.ToString()) %>',
73 '<%=ResolveUrl("~/Init/Entry/Edit/EntryType.aspx") %>', 700, 400);
74 }
75 function CtrlEnterDown() {
76 JSGet("<%=editToolBar.ButtonSave.ClientID %>").click();
77 }
78 </script>
79 </asp:Content>
数据编辑页面Nasa.App.Web/Init/Entry/Edit/Default.aspx.cs的代码:
1 using System;
2 using System.Web.UI.WebControls;
3 using Nasa.App.Init.Entry;
4 using Nasa.App.Web.Core;
5
6 namespace Nasa.App.Web.Init.Entry.Edit
7 {
8 [System.ComponentModel.DataObject]
9 public partial class Default : BasePage
10 {
11 IInitEntryManager manager = CreateRefObj<IInitEntryManager>();
12
13 public override Module ModuleID
14 {
15 get { return Module.InitEntry; }
16 }
17
18 protected void Page_Load(object sender, EventArgs e)
19 {
20 InitEdit(view, editToolBar, editKey);
21 }
22
23 [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
24 public InitEntryModel GetModel(int key)
25 {
26 if (!CanEdit)
27 return null;
28 return manager.GetModel(key);
29 }
30
31 [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Update)]
32 public void UpdateModel(InitEntryModel model)
33 {
34 if (!CanEdit)
35 throw GetNotAuthorizationException();
36 model.UpdateUser = AppUser.Id;
37 manager.UpdateModel(model);
38 }
39
40 [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Insert)]
41 public void AddModel(InitEntryModel model)
42 {
43 if (!CanEdit)
44 throw GetNotAuthorizationException();
45 model.UpdateUser = AppUser.Id;
46 EditKey = manager.AddModel(model);
47 }
48
49 protected void editToolBar_SaveClick(object sender, EventArgs e)
50 {
51 try
52 {
53 if (view.CurrentMode == DetailsViewMode.Insert)
54 {
55 view.InsertItem(true);
56 editKey.Value = EditKey.ToString();
57 ChangeMode(view, editToolBar, DetailsViewMode.Edit);
58 }
59 else
60 view.UpdateItem(true);
61 CacheData.Remove(CacheData.EntryKey);
62 ShowMessage(MsgSaveSuccessfully);
63 }
64 catch (Exception exc)
65 {
66 ShowMessage(Master, exc, view);
67 }
68 }
69
70 protected void editToolBar_UndoClick(object sender, EventArgs e)
71 {
72 view.RefreshData();
73 }
74
75 protected void editToolBar_CreateClick(object sender, EventArgs e)
76 {
77 ChangeMode(view, editToolBar, DetailsViewMode.Insert);
78 }
79 }
80 }
业务逻辑接口Nasa.App/Init/Entry/IInitEntryManager.cs
1 using Nasa.Data;
2
3 namespace Nasa.App.Init.Entry
4 {
5 public interface IInitEntryManager
6 {
7 InitEntryModels GetModels(QueryCriteria criteria);
8
9 InitEntryModel GetModel(int id);
10
11 int AddModel(InitEntryModel model);
12
13 void UpdateModel(InitEntryModel model);
14
15 void DeleteModel(InitEntryModel model);
16
17 KeyTextList GetEntry(int type);
18
19 KeyTextList GetEntryType();
20 }
21 }
业务逻辑默认实现Nasa.App/Init/Entry/InitEntryManager.cs
1 using System;
2 using Nasa.Data;
3
4 namespace Nasa.App.Init.Entry
5 {
6 public class InitEntryManager : MarshalByRefObject, IInitEntryManager
7 {
8 public InitEntryModels GetModels(QueryCriteria criteria)
9 {
10 InitEntryTable table = new InitEntryTable();
11 ColumnDictionary columns = ColumnDictionary.Get(typeof(InitEntryModel), table);
12 SelectSqlCommand sql = DataAccess.InitDB
13 .Select(table, table.AllColumns())
14 .SetCriteria(criteria, columns)
15 .OrderBy(table.UpdateDate.Desc);
16
17 using (SafeDataReader sdr = sql.ToSafeDataReader())
18 {
19 InitEntryModels result = new InitEntryModels();
20 while (sdr.Read())
21 {
22 InitEntryModel m = new InitEntryModel();
23 #region
24 m.Id = sdr.GetInt32(table.Id);
25 m.Key = sdr.GetString(table.Key);
26 m.Value = sdr.GetString(table.Value);
27 m.Type = sdr.GetInt32(table.Type);
28 m.Remark = sdr.GetString(table.Remark);
29 m.Active = sdr.GetBoolean(table.Active);
30 m.UpdateUser = sdr.GetInt32(table.UpdateUser);
31 m.UpdateDate = sdr.GetDateTime(table.UpdateDate);
32 #endregion
33 result.Add(m);
34 }
35 return result;
36 }
37 }
38
39 public int AddModel(InitEntryModel model)
40 {
41 CheckModel(model, true);
42 model.UpdateDate = System.DateTime.Now;
43 InitEntryTable table = new InitEntryTable();
44 model.Id = DataAccess.InitDB.Insert(table)
45 .AddColumn(table.Key, model.Key)
46 .AddColumn(table.Value, model.Value)
47 .AddColumn(table.Type, model.Type)
48 .AddColumn(table.Remark, model.Remark)
49 .AddColumn(table.Active, model.Active)
50 .AddColumn(table.UpdateUser, model.UpdateUser)
51 .AddColumn(table.UpdateDate, model.UpdateDate)
52 .ExecuteIdentity(table.Id);
53 return model.Id;
54 }
55
56 public void UpdateModel(InitEntryModel model)
57 {
58 CheckModel(model, false);
59 model.UpdateDate = System.DateTime.Now;
60 InitEntryTable table = new InitEntryTable();
61 DataAccess.InitDB.Update(table)
62 .AddColumn(table.Key, model.Key)
63 .AddColumn(table.Value, model.Value)
64 .AddColumn(table.Type, model.Type)
65 .AddColumn(table.Remark, model.Remark)
66 .AddColumn(table.Active, model.Active)
67 .AddColumn(table.UpdateUser, model.UpdateUser)
68 .AddColumn(table.UpdateDate, model.UpdateDate)
69 .Where(table.Id == model.Id)
70 .Execute();
71 }
72
73 public void DeleteModel(InitEntryModel model)
74 {
75 InitEntryTable table = new InitEntryTable();
76 DataAccess.InitDB.Delete(table)
77 .Where(table.Id == model.Id)
78 .Execute();
79 }
80
81 protected bool Exists(InitEntryModel model, bool isNew)
82 {
83 InitEntryTable table = new InitEntryTable();
84 SelectSqlCommand sql = DataAccess.InitDB
85 .Select(table, QueryColumn.All().Count());
86 if (model.Type > 0)
87 sql.Where(table.Key == model.Key);
88 else
89 sql.Where(table.Value == model.Value);
90 if (!isNew)
91 sql.Where(table.Id != model.Id);
92 return sql.ToScalar<int>() > 0;
93 }
94
95 public void CheckModel(InitEntryModel model, bool isNew)
96 {
97 Validator v = new Validator();
98 //Check model's data here.
99 v.Require(model.Type, "Type");
100 if (model.Type > 0 && v.Require(model.Key, "Key") && v.MaxLength(model.Key, 32, "Key"))
101 {
102 v.Assert(!Exists(model, isNew), "Key", ErrorText.Exists);
103 }
104 if (model.Type < 0)
105 {
106 v.Assert(!Exists(model, isNew), "Value", ErrorText.Exists);
107 }
108 v.Require(model.Value, "Value");
109 v.MaxLength(model.Value, 128, "Value");
110 if (!v.IsValid)
111 throw new ValidationException(v);
112 }
113
114 public InitEntryModel GetModel(int id)
115 {
116 InitEntryTable table = new InitEntryTable();
117 SelectSqlCommand sql = DataAccess.InitDB
118 .Select(table, table.AllColumns())
119 .Where(table.Id == id);
120 using (SafeDataReader sdr = sql.ToSafeDataReader())
121 {
122 InitEntryModel m = new InitEntryModel();
123 if (sdr.Read())
124 {
125 #region
126 m.Id = sdr.GetInt32(table.Id);
127 m.Key = sdr.GetString(table.Key);
128 m.Value = sdr.GetString(table.Value);
129 m.Type = sdr.GetInt32(table.Type);
130 m.Remark = sdr.GetString(table.Remark);
131 m.Active = sdr.GetBoolean(table.Active);
132 m.UpdateUser = sdr.GetInt32(table.UpdateUser);
133 m.UpdateDate = sdr.GetDateTime(table.UpdateDate);
134 #endregion
135 }
136 return m;
137 }
138 }
139
140
141 public KeyTextList GetEntry(int type)
142 {
143 VInitEntryView table = new VInitEntryView();
144 SelectSqlCommand sql = DataAccess.InitDB
145 .Select(table, table.Key, table.Value)
146 .Where(table.Type == type);
147 using (SafeDataReader sdr = sql.ToSafeDataReader())
148 {
149 KeyTextList m = new KeyTextList();
150 while (sdr.Read())
151 {
152 m.Add(sdr.GetString(table.Key), sdr.GetString(table.Value));
153 }
154 return m;
155 }
156 }
157
158 public KeyTextList GetEntryType()
159 {
160 InitEntryTable table = new InitEntryTable();
161 SelectSqlCommand sql = DataAccess.InitDB
162 .Select(table, table.Id, table.Value)
163 .Where(table.Active == true && table.Type == -1);
164 using (SafeDataReader sdr = sql.ToSafeDataReader())
165 {
166 KeyTextList m = new KeyTextList();
167 while (sdr.Read())
168 {
169 m.Add(sdr.GetInt32(table.Id), sdr.GetString(table.Value));
170 }
171 return m;
172 }
173 }
174 }
175 }
浙公网安备 33010602011771号