在WCF项目中使用Rss20FeedFormatter类时,我试图用<![CDATA[ ]]>
节包装我的描述元素的内容。我发现无论我做什么,描述元素的HTML内容总是经过编码的,而CDATA部分却从未添加。查看Rss20FeedFormatter的源代码后,我发现在构建Summary节点时,它基本上会创建一个新的TextSyndicationContent实例,该实例将清除先前指定的任何设置(我认为)。
我的代码
public class CDataSyndicationContent : TextSyndicationContent
{
public CDataSyndicationContent(TextSyndicationContent content)
: base(content)
{
}
protected override void WriteContentsTo(System.Xml.XmlWriter writer)
{
writer.WriteCData(Text);
}
}
...(以下代码应将“摘要”与“CDATA”部分一起包装起来)
SyndicationItem item = new SyndicationItem();
item.Title = new TextSyndicationContent(name);
item.Summary = new CDataSyndicationContent(
new TextSyndicationContent(
"<div>This is a test</div>",
TextSyndicationContentKind.Html));
Rss20FeedFormatter代码
(AFAIK,由于这种逻辑,上面的代码无法正常工作)
...
else if (reader.IsStartElement("description", ""))
result.Summary = new TextSyndicationContent(reader.ReadElementString());
...
作为一种解决方法,我求助于使用RSS20FeedFormatter构建RSS,然后手动修补RSS。例如:
StringBuilder buffer = new StringBuilder();
XmlTextWriter writer = new XmlTextWriter(new StringWriter(buffer));
feedFormatter.WriteTo(writer ); // feedFormatter = RSS20FeedFormatter
PostProcessOutputBuffer(buffer);
WebOperationContext.Current.OutgoingResponse.ContentType =
"application/xml; charset=utf-8";
return new MemoryStream(Encoding.UTF8.GetBytes(buffer.ToString()));
...
public void PostProcessOutputBuffer(StringBuilder buffer)
{
var xmlDoc = XDocument.Parse(buffer.ToString());
foreach (var element in xmlDoc.Descendants("channel").First()
.Descendants("item")
.Descendants("description"))
{
VerifyCdataHtmlEncoding(buffer, element);
}
foreach (var element in xmlDoc.Descendants("channel").First()
.Descendants("description"))
{
VerifyCdataHtmlEncoding(buffer, element);
}
buffer.Replace(" xmlns:a10=\"http://www.w3.org/2005/Atom\"",
" xmlns:atom=\"http://www.w3.org/2005/Atom\"");
buffer.Replace("a10:", "atom:");
}
private static void VerifyCdataHtmlEncoding(StringBuilder buffer,
XElement element)
{
if (!element.Value.Contains("<") || !element.Value.Contains(">"))
{
return;
}
var cdataValue = string.Format("<{0}><![CDATA[{1}]]></{2}>",
element.Name,
element.Value,
element.Name);
buffer.Replace(element.ToString(), cdataValue);
}
解决方法的想法来自以下位置,我只是将其调整为与WCF而不是MVC一起使用。 http://localhost:8732/Design_Time_Addresses/SyndicationServiceLibrary1/Feed1/
我只是想知道这是否只是Rss20FeedFormatter中的错误,还是设计使然?另外,如果有人有更好的解决方案,我也希望听听!
最佳答案
@Page Brooks,我更多地将其视为解决方案,然后再提出问题:)。谢谢!!!回答您的问题(;)),是的,我绝对认为这是Rss20FeedFormatter中的一个错误(尽管我没有深入探讨),因为遇到了与您所描述的完全相同的问题。
您的帖子中有一个“localhost:8732”引荐,但在我的localhost上不可用;)。我认为您打算将“PostProcessOutputBuffer”解决方法归功于此文章:
http://damieng.com/blog/2010/04/26/creating-rss-feeds-in-asp-net-mvc
或实际上它不在这篇文章中,而是在大卫·惠特尼(David Whitney)对它的评论中,他后来在这里发表了要点:
https://gist.github.com/davidwhitney/1027181
感谢您为我提供了更多解决方案,以适应我的需求,因为我也找到了解决方案,但仍在努力从MVC进行适应。现在,我只需要调整您的解决方案,即可将RSS提要放到我正在使用它的.ashx处理程序中的当前Http请求中。
基本上,我猜您使用CDataSyndicationContent提到的修复程序来自2011年2月,假设您从这篇文章中得到了修复(至少我是这样做的):
SyndicationFeed: Content as CDATA?
由于Rss20FeedFormatter的代码更改为您在帖子中输入的内容,因此此修复程序停止在某些较新的ASP.NET版本中工作。此代码更改可能也对MVC框架中IS的其他内容进行了改进,但是对于使用CDataSyndicationContent修复程序的用户而言,它肯定会导致错误!
关于wcf - Rss20FeedFormatter忽略SyndicationItem.Summary的TextSyndicationContent类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7204840/