Вопрос по asp.net, rss, syndication-feed, syndication-item – SyndicationFeed: контент в формате CDATA?

4

Я использую .NET SyndicationFeed для создания каналов RSS и ATOM. К сожалению, мне нужно содержимое HTML в элементе description (свойство Content объекта SyndicationItem), и средство форматирования автоматически кодирует HTML, но я бы предпочел, чтобы весь элемент описания был заключен в CDATA без кодирования HTML.

Мой (простой) код:

var feed = new SyndicationFeed("Title", "Description", 
               new Uri("http://someuri.com"));
var items = new List<SyndicationItem>();

var item = new SyndicationItem("Item Title", (string)null, 
               new Uri("http://someitemuri.com"));

item.Content = SyndicationContent.CreateHtmlContent("<b>Item Content</b>");

items.Add(item);
feed.Items = items;

Кто-нибудь знает, как я могу сделать это с помощью SyndicationFeed? Мое последнее средство - «вручную» создайте XML для каналов, но я бы лучше использовал встроенный SyndicationFeed.

Ваш Ответ

9   ответов
1

XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreComments = false;
            //settings.ProhibitDtd = false;
            using (XmlReader reader = XmlReader.Create(rssurl, settings))
0

.Content = SyndicationContent.CreateXhtmlContent("<![CDATA[The <em>content</em>]]>")

Это будет выведено в XML как

<entry>
  …
  <content type="xhtml"><![CDATA[The <em>content</em>]]></content>
  …
</entry>

Признаюсь, это не элегантное решение, но оно работает правильно & # x2013; только что примерил мой проект.

1

но я оставляю свое решение. Я добавил его как ElementExtension, тогда он работает для меня. Моя среда .NET 4.5.

XNamespace nsDefault = "http://www.w3.org/2005/Atom";
var content = new XElement(nsDefault + "content");
content.Add(new XCData("<b>Item Content</b>"));
item.ElementExtensions.Add(new SyndicationElementExtension(content));
-3

item.Content = "<![CDATA[" + 
            SyndicationContent.CreateHtmlContent("<b>Item Content</b>") + "]]>";
спасибо, но не работает (ошибка компилятора), так как item.Content требует объект SyndicationContent. Обратный путь также не работает, контент, включающий CDATA-теги, кодируется: item.Content = SyndicationContent.CreateHtmlContent (& lt;! [CDATA [& quot; + & lt; b & gt; Item Content & lt; / b & gt; & quot; + & quot;] & gt;) & quot ;; Hannes Sachsenhofer
8

public class CDataSyndicationContent : TextSyndicationContent
{
    public CDataSyndicationContent(TextSyndicationContent content)
        : base(content)
    {}

    protected override void  WriteContentsTo(System.Xml.XmlWriter writer)
    {
        writer.WriteCData(Text);
    }
}

тогда ты можешь:

new CDataSyndicationContent(new TextSyndicationContent(content, TextSyndicationContentKind.Html))
Это также сработало для меня.
Отличное решение, именно то, что я искал.
Я попытался сделать то же самое - новый CDataSyndicationContent (новый TextSyndicationContent (& lt; img src = \ & quot; image.jpg \ & quot; / & gt; & lt; br / & gt; & lt; br / & gt; & quot; + d.Description, TextSyndicationContentKind.Html)); но это все еще кодирует HTML? При трассировке кода, WriteContentsTo никогда не вызывается.
4

для кого решение, предлагаемое cpowers и WonderGrub, также не сработало, вам следует проверить следующий ТАК вопрос, потому что для меня этот вопрос был ответом на мое возникновение этой проблемы! Rss20FeedFormatter Игнорирует тип TextSyndicationContent для SyndicationItem.Summary

Судя по положительному ответу отthelsdj а такжеAndy Rose и затем позже "отрицательный"; ответ отTimLeung и альтернатива, предлагаемаяWonderGrub Я бы оценил, что исправление, предлагаемое cpowers, перестало работать в какой-то более поздней версии ASP.NET или что-то еще.

В любом случае решение в вышеприведенной статье SO (полученной из кода Дэвида Уитни) решило проблему с нежелательным кодированием HTML в блоках CDATA в канале RSS 2.0 для меня. Я использовал его в приложении ASP.NET 4.0 WebForms.

1

public class XmlCDataWriter : XmlTextWriter
       {
           public XmlCDataWriter(TextWriter w): base(w){}

           public XmlCDataWriter(Stream w, Encoding encoding): base(w, encoding){}

           public XmlCDataWriter(string filename, Encoding encoding): base(filename, encoding){}

           public override void WriteString(string text)
           {
               if (text.Contains("<"))
               {
                   base.WriteCData(text);
               }
               else
               {
                   base.WriteString(text);
               }
           }

       }

А затем использовать класс:

public StringBuilder CDataOverwir,iteMethod(Rss20FeedFormatter formatter)
       {
           var buffer = new StringBuilder();

           //could be streamwriter as well
           using (var stream = new StringWriter(buffer))
           {
               using (var writer = new XmlCDataWriter(stream))
               {
                   var settings = new XmlWriterSettings() {Indent = true};

                   using (var xmlWriter = XmlWriter.Create(writer, settings))
                   {
                       formatter.WriteTo(xmlWriter);
                   }
               }
           }

           return buffer;
       }
2

что и в некоторых случаях, когда переопределение WriteContentsTo не вызывалось в примере cpowers (до сих пор не знаю, почему). Итак, я изменил его, чтобы наследовать от класса SyndicationContent вместо этого. Не уверен, что это лучшее решение, но отлично сработало в моей ситуации.

public class CDataSyndicationContent : SyndicationContent
{
    public CDataSyndicationContent(string content)
    {
        Text = content;
    }

    public override SyndicationContent Clone()
    {
        return new CDataSyndicationContent(Text);
    }

    public override string Type
    {
        get { return "html"; }
    }

    public string Text { get; private set; }

    protected override void WriteContentsTo(XmlWriter writer)
    {
        writer.WriteCData(Text);
    }
}
Казалось бы, функциональность различается в зависимости от версий .NET, но это решение @WonderGrub исправило это для меня в .NET 4.0. Чтобы установить контент, просто используйте:item.Content = new CDataSyndicationContent("<b>Item Content</b>")
3

item.Content =  new TextSyndicationContent("<b>Item Content</b>",TextSyndicationContentKind.Html);
SyndicationContent.CreateHtmlContent () заключает в себе вышеприведенное, поэтому результат будет одинаковым в зависимости от того, что вы используете. Я полагаю, что проблема возникает, когда вы пытаетесь записать канал в XmlWriter.

Похожие вопросы