一共有 5 个控制器。
1. ContentCotroller
1: [Controls(typeof(AbstractPage))]<!--CRLF-->
2: public class ContentController : ContentController<!--CRLF-->
3: {
<!--CRLF-->
4: }
<!--CRLF-->
Controls特性指定控制器要使用哪种类型的内容项(模型),这里指定的是AbstractPage,而不是ContentPage,说明它可以使用任何一种内容项,不过有些内容项已经有对应的控制器了,只有没有对应控制器的内容项才会被这个控制器使用。
另外可以看出,控制器的父类被指定为ContentController,这是N2中定义的控制器类,这个类中实现了Index方法(虚拟方法),对于普通内容项已经够用,所以这里不需要重写了。
2. NewsController
1: [Controls(typeof(NewsPage))]<!--CRLF-->
2: public class NewsController : ContentController<!--CRLF-->
3: {
<!--CRLF-->
4: public override ActionResult Index()<!--CRLF-->
5: {
<!--CRLF-->
6: var vd = new NewsViewData<!--CRLF-->
7: {
<!--CRLF-->
8: News = CurrentItem,
<!--CRLF-->
9: Back = CurrentItem.Parent,
<!--CRLF-->
10: Comments = CurrentItem.GetComments()
<!--CRLF-->
11: };
<!--CRLF-->
12: return View("index", vd);<!--CRLF-->
13: }
<!--CRLF-->
14:
<!--CRLF-->
15: public ActionResult Comment()<!--CRLF-->
16: {
<!--CRLF-->
17: return View("Comment", CurrentItem);<!--CRLF-->
18: }
<!--CRLF-->
19:
<!--CRLF-->
20: public ActionResult Submit(string title, string text)<!--CRLF-->
21: {
<!--CRLF-->
22: CommentItem comment = Engine.Definitions.CreateInstance(CurrentItem);
<!--CRLF-->
23: comment.Title = Server.HtmlEncode(title);
<!--CRLF-->
24: comment.Text = Server.HtmlEncode(text);
<!--CRLF-->
25: Engine.Persister.Save(comment);
<!--CRLF-->
26:
<!--CRLF-->
27: return RedirectToAction("index");<!--CRLF-->
28: }
<!--CRLF-->
29: }
<!--CRLF-->
它控制新闻内容及其评论内容的所有请求和处理,包括获取某条新闻及其对它的所有评论、显示添加评论表单和提交评论。注意这里用到了NewsViewData类,这是视图数据类,它提供了新闻所需要的包括自己在内的必要信息,这个类在下篇中会看到代码。
Index方法在这里重写了,因为显示新闻内容的时候,还需要显示针对此新闻的所有评论和其他的一些辅助内容,比如后退到哪里,所以另外定义了专门的NewsViewData类来存储这些数据,并绑定到视图中。
Comment方法响应GET请求,它把添加评论的视图返回到浏览器让用户能够输入评论。
Submit方法响应POST请求,它负责创建一条评论对象并持久化。Engine.Definitions.CreateInstance(CurrentItem)的作用是在当前新闻内容项的子结点中添加一个评论项对象,设置了标题和文本之后,通过Engine.Persister.Save()方法把这个评论持久化到数据源中。最后回到新闻页面。
这里需要好好研究Engine对象,它提供了许多管理N2所必需的功能,如果以后要深度定制CMS的话,肯定会用的到。
3. NewsContainerController
1: [Controls(typeof(NewsContainer))]<!--CRLF-->
2: public class NewsContainerController : ContentController<!--CRLF-->
3: {
<!--CRLF-->
4: public override ActionResult Index()<!--CRLF-->
5: {
<!--CRLF-->
6: return View("Index", new NewsContainerViewData { Container = CurrentItem, News = CurrentItem.GetNews()});<!--CRLF-->
7: }
<!--CRLF-->
8:
<!--CRLF-->
9: public ActionResult JsonList()<!--CRLF-->
10: {
<!--CRLF-->
11: var news = CurrentItem.GetNews().Select(n => new { n.Title, n.Url });<!--CRLF-->
12: return Json(news);<!--CRLF-->
13: }
<!--CRLF-->
14: }
<!--CRLF-->
这个控制器的作用就是获取所有的新闻,然后传给新闻容器视图。这里也用到了视图数据类,NewsContainerViewData,它存储了新闻容器项和所有的新闻列表。
这里还定义了一个JsonList方法,返回JSON格式的新闻列表,不知道会在哪里用到。
4. TextPartController
1: [Controls(typeof(Models.TextPart))]<!--CRLF-->
2: public class TextPartController : ContentController<!--CRLF-->
3: {
<!--CRLF-->
4: public override ActionResult Index()<!--CRLF-->
5: {
<!--CRLF-->
6: return View(CurrentItem);<!--CRLF-->
7: }
<!--CRLF-->
8: }
<!--CRLF-->
这里没有什么好说的,我感觉Index没有必要重写,因为父类的Index方法就是这样写的。
5. StaticController
代码不需要贴了,这个类没有用到N2的任何代码,似乎就是用VS新建的MVC项目中的HomeController改的。它不受N2的任何控制,也不会在N2的管理界面中出现,不过它可以和N2共存。