上回书说到,VisualWiki系统已经有了显示、编辑、历史页面,不过,程序里也有了一小段重复的代码,所以我们这一次先进行一点儿重构工作。

  首先,在VisualWiki.Models里建立一个Helpers目录,然后在其中创建一个CommonHelper类,并且把我们设置HyperLink的代码整理成一个SetLink函数:

代码

namespace VisualWiki.Models.Helpers
{
    public static class CommonHelper
    {
        public static void SetLink(HyperLink link, string pageName, string linkPageName, string title)
        {
            if (pageName.ToLower() == linkPageName.ToLower())
            {
                link.Enabled = false;
            }
            else
            {
                link.Enabled = true;
                link.NavigateUrl = new UrlBuilder(linkPageName).Add("title", title).ToString();
            }
        }
    }
}

  然后打开web.config,找到pages段,在namespaces里增加这个新的namespace:

<add namespace="VisualWiki.Models.Helpers"/>

  Main.master的Page_Load函数也可以修改为:

代码

protected void Page_Load(object sender, EventArgs e)
{
    var pageName = Request.Url.Segments[2];
    CommonHelper.SetLink(Edit, pageName, "Edit.aspx", title);
    CommonHelper.SetLink(History, pageName, "History.aspx", title);
}

  运行程序,验证HyperLink工作的和以前一样,title这个字符串用的到处都是,也不太好,再在Helpers里加一个Const类,用来定义一些常量,把程序里的替换掉吧:

代码

namespace VisualWiki.Models.Helpers
{
    public static class Const
    {
        public static readonly string TitleName = "title";
        public static readonly string HomeName = "Home";
    }
}

  好的,现在来考虑另一个问题:怎么新增Wiki页?有一个新增按钮,然后填写标题和内容么?我不喜欢这样,另外,怎么在一个Wiki页里链接到另一个Wiki页呢?恩,不需要我们考虑的太多,SharePoint中的Wiki的处理方法就很好,一个Wiki页中,双中括号内的文字,就是另一篇Wiki的标题,它会被显示为一个链接,点击链接,到达另一个Wiki页,这时如果还没有建立新的Wiki页,点击Edit链接就可以了,和Home页一样。所以,我们需要一个函数,提取双中括号内的内容,并且替换成一个超链接,查找替换操作很容易出现差1的问题,对于内部有html标签的情况,也要把标签去除,另外,对于只有左双中括号,或者只有右双中括号的情况,也需要能处理,所以,先写几个单元测试吧:

代码

namespace VisualWiki.UnitTests
{
    [TestFixture]
    public class TestHelper
    {
        [Test]
        public void TestTestGenerateShowTest1()
        {
            const string text = "abc [[bb]] xyz";
            var act = CommonHelper.GenerateShowText(text);
            Assert.AreEqual("abc <a href=\"Show.aspx?title=bb\">bb</a> xyz", act);
        }

[Test]
        public void TestTestGenerateShowTest2()
        {
            const string text = "abc [[bb xyz";
            var act = CommonHelper.GenerateShowText(text);
            Assert.AreEqual("abc [[bb xyz", act);
        }

[Test]
        public void TestTestGenerateShowTest3()
        {
            const string text = "abc bb]] xyz";
            var act = CommonHelper.GenerateShowText(text);
            Assert.AreEqual("abc bb]] xyz", act);
        }

[Test]
        public void TestTestGenerateShowTest4()
        {
            const string text = "[[bb]]";
            var act = CommonHelper.GenerateShowText(text);
            Assert.AreEqual("<a href=\"Show.aspx?title=bb\">bb</a>", act);
        }

[Test]
        public void TestTestGenerateShowTest5()
        {
            const string text = "[[x<b>y</b>z]]";
            var act = CommonHelper.GenerateShowText(text);
            Assert.AreEqual("<a href=\"Show.aspx?title=xyz\">x<b>y</b>z</a>", act);
        }

[Test]
        public void TestTestGenerateShowTest6()
        {
            const string text = "[[bb]] aa [[cc]]";
            var act = CommonHelper.GenerateShowText(text);
            Assert.AreEqual("<a href=\"Show.aspx?title=bb\">bb</a> aa <a href=\"Show.aspx?title=cc\">cc</a>", act);
        }
    }
}

  写这个函数,算不上很困难,但也不是很简单,经过几次小折腾,应该就可以让所有的单元测试通过了:

代码

public static string GenerateShowText(string text)
{
    var ret = new StringBuilder();
    int last = 0;
    while (true)
    {
        int m = text.IndexOf("[[", last);
        if (m >= last)
        {
            int n = text.IndexOf("]]", m);
            if (n > m)
            {
                ret.Append(text.Substring(last, m - last));
                var title = text.Substring(m + 2, n - m - 2);
                var url = new UrlBuilder("Show.aspx");
                url.Add(Const.TitleName, RemoveHtmlTag(title));
                var link = HtmlBuilder.New.a(url.ToString()).include(title).end;
                ret.Append(link);
                last = n + 2;
                continue;
            }
        }
        ret.Append(text.Substring(last));
        break;
    }
    return ret.ToString();
}

public static string RemoveHtmlTag(string text)
{
    var ret = new StringBuilder();
    int last = 0;
    while (true)
    {
        int m = text.IndexOf("<", last);
        if (m >= last)
        {
            int n = text.IndexOf(">", m);
            if (n > m)
            {
                ret.Append(text.Substring(last, m - last));
                last = n + 1;
                continue;
            }
        }
        ret.Append(text.Substring(last));
        break;
    }
    return ret.ToString();
}

  恩,代码能工作,只不过,两个函数里有不少相似的代码,再重构一下吧:

代码

public static string GenerateShowText(string text)
{
    return ProcessSymbol(text, "[[", "]]",
        title =>
        {
            var url = new UrlBuilder("Show.aspx");
            url.Add(Const.TitleName, RemoveHtmlTag(title));
            var link = HtmlBuilder.New.a(url.ToString()).include(title).end;
            return link.ToString();
        });
}

public static string RemoveHtmlTag(string text)
{
    return ProcessSymbol(text, "<", ">", null);
}

public static string ProcessSymbol(string text, string left, string right,
    CallbackHandler<string, string> callback)
{
    var ret = new StringBuilder();
    int last = 0;
    while (true)
    {
        int m = text.IndexOf(left, last);
        if (m >= last)
        {
            int n = text.IndexOf(right, m);
            if (n > m)
            {
                ret.Append(text.Substring(last, m - last));
                if(callback != null)
                {
                    var inner = text.Substring(m + left.Length, n - m - left.Length);
                    ret.Append(callback(inner));
                }
                last = n + right.Length;
                continue;
            }
        }
        ret.Append(text.Substring(last));
        break;
    }
    return ret.ToString();
}

  运行单元测试,全部通过,既然有了可以工作的GenerateShowText函数,就把它加入Show.aspx里吧,需要修改的地方并不多,一个是原来的article.Content,一个是h.Content。修改之后,运行程序,进入Home页,编辑它,加入有双中括号的内容,比如Hello,保存,回到Show.aspx,显示Hello为链接,点击此链接,进入Hello页,在这里可以进行Hello页编辑、浏览历史等操作了。就是回不去Home页,恩,在Main.master里加个Home的链接吧:

<a href="Show.aspx?title=Home">Home</a> |

  现在,我们的Wiki系统已经基本成型,显示、编辑、新建、历史都有了,我们还想给它加入路径功能,不过,先把代码提交了吧。目前的代码:VisualWiki4.7z

  未完待续……

转载于:https://www.cnblogs.com/lephone/archive/2009/12/03/create_wiki_by_using_dbentry_4.html

DbEntry 开发实践:Wiki 系统(四)相关推荐

  1. Xamarin.Android开发实践(十四)

    原文:Xamarin.Android开发实践(十四) Xamarin.Android之ListView和Adapter 一.前言 如今不管任何应用都能够看到列表的存在,而本章我们将学习如何使用Xama ...

  2. python web开发项目 源码_Python + Flask 项目开发实践系列七

    对于 Python + Flask 这种灵活的web开发框架,在前面的六个系列文章中详细的进行了说明,主要讲到了页面的首页加载时的页面渲染,增加功能,删除功能,修改功能,查询功能,查询详情功能等一些页 ...

  3. flask python web开发 可视化开发_Python + Flask 项目开发实践系列六

    今天开始我们讲讲Flask Web实践项目开发中的查看详情功能是如何实现的. Step1:html 部分 lists +="<tr>"+ //拼凑一段html片段 &q ...

  4. 四.卡尔曼滤波器(EKF)开发实践之四: ROS系统位姿估计包robot_pose_ekf详解

    本系列文章主要介绍如何在工程实践中使用卡尔曼滤波器,分七个小节介绍: 一.卡尔曼滤波器开发实践之一: 五大公式 二.卡尔曼滤波器开发实践之二:  一个简单的位置估计卡尔曼滤波器 三.卡尔曼滤波器(EK ...

  5. 20189200余超 2018-2019-2 移动平台应用开发实践第四作业

    2018-2019-2 移动平台应用开发实践第四周作业 第12章枚举 什么情况下使用枚举类? 有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便. 为什么不用静态常量来替代枚举类呢 ...

  6. 升讯威微信营销系统开发实践:(3)功能介绍与此项目推广过程的一些体会( 完整开源于 Github)...

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  7. 小米网抢购系统开发实践和我的个人观察

    本文个人观察部分,为自己的一点看法. 正文内容,转载于 <程序员>2014年11月刊:电商峰值系统架构设计 http://www.csdn.net/article/2014-11-04/2 ...

  8. webgis从基础到开发实践_ArcGIS API For Javascript 开发笔记(四)

    二.应用篇 1.应用部署 部署也就意味着一个 DEMO 或者系统即将完工,也意味着系统即将上线,相对来说Javascript 应用的部署不是很复杂,但是这是有前提的,要对部署中的一些概念有所了解,比如 ...

  9. 《小米网抢购系统开发实践》读后感

    原文地址:    https://mp.weixin.qq.com/s/ecU_CjTluQUX-420v3nWTQ 今天读了<小米网抢购系统开发实践>这篇文章,感受如下: 首先文章介绍了 ...

  10. ArcGIS Maritime Server 开发教程(四)Maritime Service 开发实践

    ArcGIS Maritime Server 开发教程(四)Maritime Service 开发实践 本章导读:Maritime Service 属于 MapService 的一个扩展,大部分功能继 ...

最新文章

  1. Qt 事件系统的解读
  2. 2018年第九届蓝桥杯 - 省赛 - C/C++大学A组 - F.航班时间
  3. 计算机组成原理第4章,计算机组成原理-第4章总结.doc
  4. RabbiqMQ快速入门
  5. 南海发展大数据产业 建设新型智慧城市
  6. 2017.8.17 陌上花开 思考记录
  7. 团队行为守则—如果你们由我来领导
  8. 使用cJSON产生json字串
  9. typec扩展坞hdmi没反应_HDMI+两个USB接口,让surface秒变办公神器?这个扩展坞真香...
  10. 泛微oa连接mysql,泛微OA 数据库维护笔记(e-cology)
  11. 利用动态数组生成魔方矩阵
  12. 空间线与空间平面之间的夹角关系
  13. mysql正则时间格式_用正则表达式校验时间格式的正确性
  14. Connection Backoff Interop Test Descriptions
  15. win7 快捷键 收集
  16. 服务器版本的ansys证书错误,关于ANSYS Workbench 出现证书错误的解决办法
  17. 为什么HikariCP是性能最好的数据库连接池?
  18. Polkadot 基础
  19. [视觉模型]迁移学习之五个步骤
  20. 【海康威视研究院】杭州3面试记录

热门文章

  1. arch终端添加中文支持_arch/manjaro - 添加archlinuxcn的软件源
  2. sqlerver 字符串转整型_Sqlerver进行模糊查询like和转义字符
  3. Java基础0308
  4. 《转》牛顿法与拟牛顿法学习笔记
  5. MySQL查询当天、本周,本月,上一个月的数据
  6. hadoop deployment
  7. C# ToString()日期格式
  8. 用mapreduce 处理气象数据集
  9. cassandra根据用户名密码登录cqlsh
  10. AngularJS 模板