【问题标题】:asp.net mvc 3 regular expression returning encoded html?asp.net mvc 3 正则表达式返回编码的html?
【发布时间】:2011-05-15 08:44:54
【问题描述】:
public static string MakeAnchor(string text) 
{
    string pattern = @"((?<Protocol>\w+):\/\/(?<Domain>[\w@][\w.:@]+)\/?[\w\.?=%&=\-@/$,]*)";
    Regex r = new Regex(pattern, RegexOptions.Multiline);
    var anchor = r.Replace(text, "<a href=\"$1\" target=\"_blank\">$1</a>");
    return anchor;
}

如果我传递一些包含http://google.com/ 的文本,此方法将返回&amp;lt;a href=&amp;quot;http://google.com/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;http://google.com/&amp;lt;/a&amp;gt;

而不是&amp;lt;a href=&amp;quot;http://google.com/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;http://google.com/&amp;lt;/a&amp;gt;

我在 MVC 3 中使用剃刀视图。我很难过。 MVC 3 中是否有某种我不知道的新视图编码?

【问题讨论】:

  • 该方法实际上并没有显示它在调试器中返回编码字符串,只是视图是这样写的。

标签: asp.net regex asp.net-mvc-3 razor


【解决方案1】:

如果您使用@:(在 Razor 中)或

【讨论】:

    【解决方案2】:

    让您的方法返回一个IHtmlString 以向框架表明您的输出已经编码。

    最简单的实现是return new HtmlString(anchor);

    IHtmlString 是在 .NET 4 中实现的,因此如果您使用的是 .NET 3.5,则必须使用 @=&lt;%= 语法(如 @Andrew 所述)以避免编码。

    【讨论】:

      【解决方案3】:

      我发现这篇博文 (http://www.akngo.com/) 展示了如何“包装”Htmlstring 以方便起见。用法是 RawView.SomeString

      我一直在使用 Razor 引擎 几天了,我喜欢它 很多。我注意到了一个大问题 从一开始,所有字符串都是 HTML 编码。对于我们的使用,这变成 当我们 处理 JSON 字符串。例如, 给定一个简单的 JSON 字符串 ["1", "2", "3", "4"]

      这个的实际 HTML 编码输出 变成了 ["1", "2", "3", "4"]

      引号已被转义,即 不是所需的输出。如果我们需要 发回 HTML 或 XML,我们会 然后必须单独逃脱 那些。总的来说,我觉得这很 烦人,因为我们必须把它包起来 在 HtmlString 内部,如图所示 这个 StackOverflow 帖子。

      在我们的场景中,我们正在生成 来自 C# 的 JSON/XML,所以大多数时候, 我们的序列化数据在 视图模型。这将导致我们 像@(新 HtmlString(View.Foo)) @(新 HtmlString(View.Bar))

      如您所见,这可以变得相当 麻烦。所以我决定 剽窃 MVC 的一部分以创建一个 原始视图。最后,使用将 是,@RawView.Foo @RawView.Bar

      我也继续允许使用 索引运算符以及以防万一 需要用一个循环遍历它 键列表。 // 假设我们有 Foo, 我们的 ViewModel 中的 Bar 和 Baz @{ 列表键 = 新列表 { "Foo", "Bar", "Baz" }; foreach(键中的var键){ @RawView[键] } }

      要实现这一点,我需要 复制 DynamicViewDataDictionary。 自然是我给它取名 DynamicRawViewDataDictionary,公共 类 DynamicRawViewDataDictionary : 动态对象 { 私有只读 Func viewThunk; 公共 DynamicRawViewDataDictionary(Func viewTunk) { this.viewThunk = viewThunk; }

          private ViewDataDictionary ViewData
          {
              get
              {
                  ViewDataDictionary viewData = this.viewThunk();
                  return viewData;
              }
          }
      
          public object this[string key]
          {
              set { setData(key, value); }
              get { return getData(key); }
          }
      
          public override IEnumerable<string>
      

      GetDynamicMemberNames() { 返回 ViewData.Keys; }

          public override bool TryGetMember(GetMemberBinder binder,
      

      输出对象结果) { 结果 = getData(binder.Name); 返回真; }

          public override bool TrySetMember(SetMemberBinder binder,
      

      对象值) { setData(binder.Name, value); 返回真; }

          private object getData(string key)
          {
              object value = ViewData[key];
              if (value is string)
              {
                  return new HtmlString(value.ToString());
              }
      
              return value;
          }
      
          private void setData(string key, object value)
          {
              ViewData[key] = value;
          }
      }
      

      重复的原因是 因为 DynamicViewDataDictionary 是一个内部密封类。有 我没办法解决这个问题 复制以外的限制和 粘贴。我做出的明显改变 这个类是getData 方法。一世 检查对象是否是 字符串,如果是,我用一个 htmlString().

      现在我需要在一个 WebViewPage,因为所有视图,我都有 有一个定制的版本 WebViewPage 也是如此。好东西 MS 没有把这个类变成内部的 密封,所以我可以很容易地继承 它。我需要制作一个通用的和一个 非通用版本,我只是扑通一声 这两个都在一个文件中。 公共抽象类 自定义WebViewPage: 网页浏览页面 { 私有 DynamicRawViewDataDictionary _rawData; 公共动态 RawView { 得到 { 如果(_rawData == null) { _rawData = new DynamicRawViewDataDictionary(() => 查看数据); } 返回_rawData; } } }

      public abstract class CustomWebViewPage : WebViewPage
      {
          private DynamicRawViewDataDictionary _rawData;
          public dynamic RawView
          {
              get
              {
                  if (_rawData == null)
                  {
                      _rawData = new DynamicRawViewDataDictionary(() =>
      

      查看数据); } 返回_rawData; } } }

      为了真正做最后的润色 这项工作,在 cshtml 的顶部 文件,你应该有类似的东西, @继承 命名空间.To.CustomWebViewPage

      //或@inherits 命名空间.To.CustomWebViewPage

      现在 cshtml 文件继承自 新的 CustomWebViewPage,它应该 可以访问 RawView,这将 用 HtmlString 包装所有字符串。

      一旦你有了这个,你就会 仍然需要确保所有 您的新视图继承自 自定义WebViewPage。我强烈推荐 在您的 MVC 项目生成视图。这 将有助于自动化很多 平凡的任务。

      【讨论】:

        【解决方案4】:

        HTML 字符串就是答案。

        @(new HtmlString(SomeString))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-28
          • 1970-01-01
          • 1970-01-01
          • 2010-11-23
          • 2011-11-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多