如何使用Razor语法获取ASP.NET MVC 4中文本中URL的链接?

我有一个带文本字段的模型。 该文本可以包含多个URL。 它不必包含URL,也没有特定的格式。

运用

@Html.DisplayFor(model => model.TextWithSomeUrls) 

当然,文本和URL显示为普通文本。 我想将URL显示为工作单个链接。 在ASP.NET / Razor中是否有一个帮助方法?

编辑 :现在输出是:

 http://www.google.com, foo: bar; http://www.yahoo.com 

这正是文本字段的内容。

但是我希望获取URL,并且只将URL呈现为如下链接:

 http://www.google.com, foo: bar; http://www.yahoo.com 

我的解决方案

 public static partial class HtmlExtensions { private const string urlRegEx = @"((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)"; public static MvcHtmlString DisplayWithLinksFor(this HtmlHelper htmlHelper, Expression<Func> expression) { string content = GetContent(htmlHelper, expression); string result = ReplaceUrlsWithLinks(content); return MvcHtmlString.Create(result); } private static string ReplaceUrlsWithLinks(string input) { Regex rx = new Regex(urlRegEx); string result = rx.Replace(input, delegate(Match match) { string url = match.ToString(); return String.Format("{0}", url); }); return result; } private static string GetContent(HtmlHelper htmlHelper, Expression<Func> expression) { Func func = expression.Compile(); return func(htmlHelper.ViewData.Model).ToString(); } } 

此扩展现在可以在视图中使用:

 @Html.DisplayWithLinksFor(model => model.FooBar) 

没有这样的帮助器,但您可以创建自己的自定义帮助程序或为DisplayFor帮助程序创建模板 ,该模板将包含您需要的逻辑。

我遇到了解决方案的一些问题:

  1. 它不适用于没有点的主机名,如localhost或任何其他LAN-URL
  2. 它对带空格的URL不起作用(小问题)
  3. 它没有编码我的所有其余数据。 因此,如果数据库中存在“<! - ”,则页面将被截断。
  4. URI未转义

我使用了上面的代码,扩展了一点,最后得到了这个:

 private static readonly Regex urlRegEx = new Regex(@"(?(this HtmlHelper htmlHelper, Expression> expression, string templateName = null) { var encodedHTML = htmlHelper.DisplayFor(expression, templateName); return MvcHtmlString.Create(ReplaceUrlsWithLinks(encodedHTML.ToHtmlString())); } private static string ReplaceUrlsWithLinks(string input) { input = input.Replace(@"\\", @"file://").Replace('\\', '/'); var result = quotedUrlRegEx.Replace(input, delegate(Match match) { string url = match.Groups[2].Value; return String.Format("{1}", Uri.EscapeUriString(url), ShortenURL(url)); }); return urlRegEx.Replace(result, delegate(Match match) { string url = match.ToString(); return String.Format("{1}", Uri.EscapeUriString(url), ShortenURL(url)); }); } private static string ShortenURL(string url) { url = url.Substring(url.IndexOf("//", StringComparison.Ordinal) + 2); if (url.Length < 60) return url; var host = url.Substring(0, url.IndexOf("/", StringComparison.Ordinal)); return host + "/…"; } 

显然没有100%测试所有的URL方案,但似乎工作正常。

示例输入:

 "\\02lanpc\abc\def\Bugs in the database.docx" http://localhost:81/applications/2/?releaseNumber=1.1&buildNumber=2 

输出:

 02lanpc/abc/def/Bugs in the database.docx localhost:81/… 

尝试编写自己的Html Helper,如下所示。

 public static string Urls(this HtmlHelper helper, string value) { var items = value.Split(';'); // use your delimiter var sb = new StringBuilder(); foreach(var i in items) { if(IsUrl(i)) // write a static method that checks if the value is a valid url sb.Append("" + i + ","); else sb.Append(i + ","); } return sb.ToString(); } 

并使用那样的

 @Html.Urls(myValue) 

如果文本包含mvc URL,则可以使用@Html.Action(actionName)