我可以将文本属性定义为富文本吗?

时间:2015-01-30 17:02:13

标签: vb.net entity-framework

VS 2013,VB,EF6

我正在创建一个对象,该对象将用户输入保留在其中一个属性中。我希望将用户输入存储为富文本。使存储的文本成为富文本格式需要做些什么?所以,

Public Property Text as <what?>

2 个答案:

答案 0 :(得分:2)

我想我会发布我的答案,对于那些可能以同样的方式提问的人。我首先说明我的问题形成不好,因为我不明白我不是真的存储RTF,我用html标签存储WYSIWYG文本。但我认为这个问题很有用,因为在他们被别人教授之前,有多少人会这么想。

最终这个过程会打开一个严肃的XSS向量,但首先我们必须至少收集WYSIWYG文本。

第一步:使用基于脚本的编辑器捕获带有html标记的文本。我使用了CKEditor,这很容易在NuGet上下载。它有三种口味:基本,标准和完整。另一个流行的似乎是TinyMCE也可以通过NuGet获得。

CKEditor必须'连接'才能替换现有的输入元素。我用&lt;替换了@ html.editorfor textarea&gt;直接如下。 Model.UserPost.Body是我想要放置WYSIWYG文本的属性。 Raw助手是必需的,因此输出不是编码的,这样我们就可以看到我们所见即所得的文本了。

<textarea name="model.UserPost.Body" id="model_UserPost_Body" class="form-control text-box multi-line">
  @Html.Raw(Model.UserPost.Body)
</textarea>

CKEditor使用脚本元素'连接'来替换&lt; textarea&gt;元件。

@Section Scripts
  <script src="~/scripts/ckeditor/ckeditor.js"></script>
  <script>
    CKEDITOR.replace('model.UserPost.Body');
  </script>
End Section

上面的脚本可以通过_layout.vbhtml添加到所有页面,或者通过@Section Scripts部分添加到目标页面,如上所示,这通常是推荐的和我做的,但这可能还需要添加到标准_在&lt;中&lt;头&gt;如下所示。

@RenderSection("Styles", False)

在视图的控制器POST方法中,需要以下代码来捕获WYSIWYG文本,否则默认过滤器会在检测到任何看起来像html标记的内容时引发异常。

Dim rawBody = Request.Unvalidated.Form("model.UserPost.Body")
userPost.Body = rawBody

有一些可能的问题;必须从Include:=&lt;列表中删除'body'属性。绑定&gt;方法参数列表中的元素是否&lt;绑定&gt;正在使用。此外,虽然与此解决方案没有直接关系,但您不能拥有像&lt;这样的数据注释。必需()&gt;在模型中的此属性上,因为后台检查将无法确认该条件,因此ModelState.IsValid标志将不会生效。

第二步:在保存输入之前,必须检查必须是否有XSS。微软有nice video explaining basic XSS我建议观看;这只有11分钟。

Mikesdotnetting对处理XSS有很好的解释,并在this page的底部显示了白名单算法。以下代码基于他的工作。

要创建白名单方法,HTML Agility Pack可用于对HTML节点进行编目以供审阅。这也很容易从Nu Get加载。这是我在POST方法中用来调用白名单方法的代码(是的,它可能更紧凑,但这对我们新手来说更容易阅读):

Dim tempDoc = New HtmlDocument()
tempDoc.LoadHtml(rawBody)
RemoveNodes(tempDoc.DocumentNode, allowedTags)
userPost.Body = tempDoc.DocumentNode.OuterHtml

允许的标签是您允许的标签,这意味着其他所有标签都被拒绝,因此白名单。这只是一个示例列表:

Dim allowedTags As New List(Of String)() From {"p", "em", "s", "ol", "ul", "li", "h1", "h2", "h3", "h4", "h5", "h6", "strong"}

这些是基于Mikesdotnetting页面的方法:

Private Sub RemoveNodes(ByVal node As HtmlNode, allowedTags As List(Of String))
  If (node.NodeType = HtmlNodeType.Element) Then
    If Not allowedTags.Contains(node.Name) Then
      node.ParentNode.RemoveChild(node)
      Exit Sub
    End If
  End If

  If (node.HasChildNodes) Then
    RemoveChildren(node, allowedTags)
  End If
End Sub

Private Sub RemoveChildren(ByVal parent As HtmlNode, allowedTags As List(Of String))
  For i = parent.ChildNodes.Count() - 1 To 0 Step -1
    RemoveNodes(parent.ChildNodes(i), allowedTags)
  Next
End Sub

基本上,(1)CKEditor使用看起来不错的html标签捕获用户输入,(2)在Controller POST方法中特别请求原始输入,然后(3)使用白色清除名单。之后,它可以使用@ Html.Raw()直接输出到页面,因为它可以被信任。

就是这样。我以前没有真正发布这样的解决方案,所以如果我错过了什么让我知道,我会更正或添加它。

答案 1 :(得分:-1)

富文本格式以富文本格式存储。

可以在此处找到富文本格式规范:

http://www.microsoft.com/en-us/download/details.aspx?id=10725

这只是一个普通的字符串。您可以使用SaveFile函数从RichTextBox中提取字符串:

Private Function GetRTF(ByRef Box As RichTextBox) As String
    Using ms As New IO.MemoryStream
        Box.SaveFile(ms, RichTextBoxStreamType.RichText)
        Return System.Text.Encoding.ASCII.GetString(ms.ToArray)
    End Using
End Function

您可以使用RichTextBox的LoadFile方法将富文本格式的文本加载到RichTextBox中。文本需要采用正确的格式:

Dim rtf As String = "{\rtf1 {\colortbl;\red0\green0\blue255;\red255\green0\blue0;}Guten Tag!\line{\i Dies} ist ein\line formatierter {\b Text}.\line Das {\cf1 Ende}.}"
Using ms As New IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes(rtf))
    RichTextBox1.LoadFile(ms, RichTextBoxStreamType.RichText)
End Using

普通控件通常不会在其文本属性中解释此格式。

相关问题