При использовании класса Rss20FeedFormatter в проекте WCF я пытался обернуть содержимое моих элементов описания разделом <![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 Code (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 или это задумано?Кроме того, если у кого-то есть лучшее решение, я бы хотел услышать его!