在 BlogEngine.Net 1.0中, Post的链接是根据Post.Title来判断的, 获取Post的相对Uri属性RelativeLink时, 关键语句是Utils.RemoveIlegalCharacters(Title),我们先看看RemoveIlegalCharacters()方法:
/// Strips all illegal characters from the specified title.
/// </summary>
public static string RemoveIlegalCharacters( string text)
{
if ( string .IsNullOrEmpty(text))
return text;
StringBuilder sb = new StringBuilder();
text = text.Replace( " " , " - " );
foreach ( char c in text)
{
if (IsAllowedCharacter(c))
sb.Append(c);
}
return sb.ToString();
}
private static bool IsAllowedCharacter( char character)
{
string allowedChars = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_- " ;
foreach ( char c in allowedChars)
{
if (c == character)
return true ;
}
return false ;
}
如果标题中有上述字符还行,要是全部由非上述字符组成的话, 如Utils.RemoveIlegalCharacters("中文标题"), 看到的链接将会是"/post/.aspx", 当有两篇全中文标题的Post时, 之前的那篇Post将不能被链接到.
为了这个解决这个问题, 我作了一些修改, 思路大概如下:
1. 当标题中包含"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"这类字符时, 按原方式进行;
2. 当标题由非""abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" 字符组成的, 则使用Post.Id进行链接, 链接的形式如: "/post/a9d8c39d-c731-43bc-9ac6-faeafcfe0fcf.aspx".
修改步骤1: 在打开BlogEngine.Net的源代码Post.cs, 修改 RelativeLink属性的实现:
/// A relative-to-the-site-root path to the post.
/// Only for in-site use.
/// </summary>
public Uri RelativeLink
{
// get { return new Uri(VirtualPathUtility.ToAbsolute("~/post/" + Utils.RemoveIlegalCharacters(Title) + ".aspx"), UriKind.Relative); }
// 当标题全部字符都是非ASCII码字符时,URL形式为: /post/a9d8c39d-c731-43bc-9ac6-faeafcfe0fcf.aspx
// 其中a9d8c39d-c731-43bc-9ac6-faeafcfe0fcf是Post的Id的字符串形式
// 改进,支持非ASCII码字符标题 --Start
get
{
string link = Utils.RemoveIlegalCharacters(Title);
if (link.Length == 0 )
{
return new Uri(VirtualPathUtility.ToAbsolute( " ~/post/ " + Id.ToString() + " .aspx " ), UriKind.Relative);
}
return new Uri(VirtualPathUtility.ToAbsolute( " ~/post/ " + link + " .aspx " ), UriKind.Relative);
}
// 改进,支持非ASCII码字符标题 --End
}
步骤2: 打开UrlRewrite.cs, 修改RewritePost()方法:
{
// string title = ExtractTitle(context, "/post/");
// Post post = Post.GetPostByName(title);
// if (post != null)
// context.RewritePath("~/post.aspx?id=" + post.Id.ToString() + GetQueryString(context), false);
// 当标题全部字符都是非ASCII码字符时,URL形式为: /post/a9d8c39d-c731-43bc-9ac6-faeafcfe0fcf.aspx
// 其中a9d8c39d-c731-43bc-9ac6-faeafcfe0fcf是Post的Id的字符串形式
// 改进,支持非ASCII码字符标题 --Start
string title = ExtractTitle(context, " /post/ " );
Post post = Post.GetPostByName(title);
if (post != null )
{
context.RewritePath( " ~/post.aspx?id= " + post.Id.ToString() + GetQueryString(context), false );
return ;
}
post = Post.GetPost( new Guid(title));
if (post != null )
{
context.RewritePath( " ~/post.aspx?id= " + post.Id.ToString() + GetQueryString(context), false );
}
// 改进,支持非ASCII码字符标题 --End
}
步骤3: 重新编译, 运行并测试:
成功!!!
类似地, 还可以修改Category, Tag等等....
希望这篇文章对你有用.
PS: 1.1版本已经修复了Title和Category的中文链接问题, 而Tag的中文链接问题的修复方法:
修改App_Code/Controls/TagCloud.cs中的RenderControl()方法替换成如下方法即可.
/// <summary>
/// Renders the control.
/// </summary>
public override void RenderControl(HtmlTextWriter writer)
{
writer.Write("<ul id=\"tagcloud\">");
foreach (string key in WeightedList.Keys)
{
writer.Write("<li>");
writer.Write(string.Format(LINK, Utils.RelativeWebRoot + "?tag=/" + HttpUtility.UrlEncode(key), WeightedList[key], "Tag: " + key, key));
writer.Write("</li>");
}
writer.Write("</ul>");
writer.Write(Environment.NewLine);
}