检测SPItemEventReceiver中富文本字段值的变化?

时间:2011-01-25 17:25:49

标签: sharepoint text sharepoint-2007

我目前有一个附加到自定义列表的事件接收器。我目前的要求是为富文本字段(具有增强的富文本的多行文本)实现列级安全性。

根据这个post,我可以得到字段之前和之后的值:

object oBefore = properties.ListItem[f.InternalName];
object oAfter = properties.AfterProperties[f.InternalName];

问题在于我遇到了比较这两个值的问题,这会导致误报(代码在没有更改时检测到更改)。

图表A:在两个对象上使用ToString

oBefore.ToString()

<div class=ExternalClass271E860C95FF42C6902BE21043F01572>
<p class=MsoNormal style="margin:0in 0in 0pt">Text. 
</div>

oAfter.ToString()

<DIV class=ExternalClass271E860C95FF42C6902BE21043F01572>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt">Text. 
</DIV>

问题?

  • HTML标记大写
  • 随机空格(请参阅margin:之后的其他空格)

使用GetFieldValueForEditGetFieldValueAsHTML似乎会产生相同的值。

“好的,”你说,所以我们只需比较纯文本值。

图表B:使用GetFieldValueAsText

幸运的是,此方法会从值中删除所有HTML标记,并且仅显示纯文本。但是,使用这种方法让我发现了空格字符的其他问题:

之前的值:

  1. 有时会有其他换行符。
  2. 有时候空格显示为不间断空格(ASCII字符代码160)
  3. 问题:

    如何检测用户是否更改了事件接收器中的富文本字段?

    1. [理想]检测对HTML或文本或空格的任何更改
    2. [可接受]检测文本或空格的更改
    3. [不太好]仅检测文本字符的更改(删除所有非字母数字字符)

3 个答案:

答案 0 :(得分:0)

如果使用新值设置ListItem字段并将其读回,会发生什么?这会给出相同的格式吗?

object oBefore = properties.ListItem[f.InternalName];
properties.ListItem[f.InternalName] = properties.AfterProperties[f.InternalName]
object oAfter = properties.ListItem[f.InternalName];
//dont update
properties.ListItem[f.InternalName] = oBefore;

答案 1 :(得分:0)

我可能会在选择2和3之间尝试一下:

bool changed =
    valueAsTextBefore != valueAsTextAfter ||
    0 != string.Compare(
        oBefore.ToString().Replace(" ", ""), 
        oAfter.ToString().Replace(" ", ""), 
        true);

左半部分检查文本(包括大小写)是否已更改,而右半部分检查标签或属性是否已更改。非常kludgy,但应该适合你的情况。

我能想到的另一件事就是在HTML上运行XML转换,以便对case和spacing进行标准化。但这不仅看起来有点矫枉过正,而且还假设HTML总是很好地形成。

答案 2 :(得分:0)

我目前正在测试一种组合方法:GetFieldValueAsText,然后删除除字母数字/标点符号以外的所有字符:

static string GetRichTextValue(string value)
{
    if (null == value)
    {
         return string.Empty;
    }
    StringBuilder sb = new StringBuilder(value.Length);
    foreach (char c in value)
    {
         if (char.IsLetterOrDigit(c) || char.IsPunctuation(c))
         {
              sb.Append(c);
         }
    }
    return sb.ToString();
}

这仅检测对富文本字段文本的更改,但似乎一致地工作。