如何使用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帮助程序创建模板 ,该模板将包含您需要的逻辑。
我遇到了解决方案的一些问题:
- 它不适用于没有点的主机名,如localhost或任何其他LAN-URL
- 它对带空格的URL不起作用(小问题)
- 它没有编码我的所有其余数据。 因此,如果数据库中存在“<! - ”,则页面将被截断。
- 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)
。