首先,在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();
}
}
}
}
{
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);
}
{
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 " ;
}
}
{
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);
}
}
}
{
[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();
}
{
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();
}
{
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
未完待续……